- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
20 个三角形,其中 7 个没有重复)。我设法通过连接 a、b、c 以 abc 格式存储所有三角形来做到这一点,但我的程-6ren">
我有一个 C 程序可以找到所有可能的三角形(例如 3 3 4 4 5 5 => 20 个三角形,其中 7 个没有重复)。我设法通过连接 a、b、c 以 abc 格式存储所有三角形来做到这一点,但我的程序太慢了。我发现找到所有三角形的函数对于 1000 个数字和 uniq() 函数需要 1.68 秒。(限制为2s):
int getTriangles(const int nosniky[], int N, int trojuhelniky[]) {
int count = 0;
tcount = 0;
// The last triangle found
int TEMP = 0;
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
for (int m = j + 1; m < N; m++) {
int a = nosniky[i];
int b = nosniky[j];
int c = nosniky[m];
if (a + b > c && a + c > b && c + b > a) {
// Order a,b,c so that a<b<c
order(&a, &b);
order(&a, &c);
order(&b, &c);
count++;
// Triangle will be stored as abc, so we need to join all ints into
// one (3,3,4 => 334)
int temp = joinInts(a, b);
if (i == 0 && j == 1 && m == 2) {
// first triangle, for example a=3,b=3,c=4 => 334
TEMP = joinInts(temp, c);
tcount++;
trojuhelniky[tcount - 1] = joinInts(temp, c);
} else if (joinInts(temp, c) == TEMP) {
// This is a duplicate, ignoring this one
} else {
tcount++;
trojuhelniky[tcount - 1] = joinInts(temp, c);
// TEMP = the new last found triangle
TEMP = joinInts(temp, c);
}
}
}
}
}
// Remove remaining duplicates, 1.68s as well
int newcount = uniq(trojuhelniky, tcount);
return newcount;
}
我对输入进行排序,将“最后找到的”三角形存储在 TEMP 变量中,然后检查下一个是否相同,如果不同,则下一个三角形是新的 TEMP。这样我就摆脱了大部分重复项,我在 uniq() 函数中删除了其余部分。
所以我的问题是,我可以做些什么来提高我的代码速度?我已经设法从 6s 到 3.2s,现在我卡住了。
最好的情况是在 3 个 for 循环中实时删除重复项,但我不知道该怎么做,所以我现在最好的选择是尝试优化我不太好的代码 :D
编辑:“三角形”是指 a+b>c、b+c>c 和 a+c>b,因此对于输入 3 3 4 4 5 5,我应该找到 20 种可能的组合来满足该要求.删除重复项后,结果应为 7(3,3,4 与 4,3,3 相同)。
编辑 2:输入范围为 3 到 1000 个随机整数。这是 uniq() 函数:
int uniq(int *a, size_t len) {
size_t i, j;
qsort(a, len, sizeof(int), icmp);
for (i = j = 0; i < len; i++) {
if (a[i] == 0) {
break;
}
if (a[i] != a[j]) a[++j] = a[i];
}
return (int) j + 1;
}
输入 2 9 18 4 1 5 19 6 3 1 2 8
的输出应该是 27。
最佳答案
首先请注意,如果您保证输入数组已排序,同时保持 i < j < m
,你永远不会得到 (3,4,3) 的组合。服用
int a = nosniky[i];
int b = nosniky[j];
int c = nosniky[m];
将使(a,b,c)
一个非递减序列。所以这根本不是问题。
但是,当您的输入数据包含重复项时,您可以获得重复项。例如,输入 3,4,4,5
你得到相同的三元组 (a,b,c) = (3,4,5) for (i,j,m) = (0,1,3) and for (i,j,m) = (0,2 ,3).
为了避免这种情况,您只需要以巧妙的方式增加 i,j,m 以跳过重复项:if nosniky[1] == 4
和 nosniky[2] == 4
你不应该增加 j
从 1 到 2,而是不断递增直到找到 nosniky[j]
不同于nosniky[j-1]
(或者您点击 j == N
)。
int count = 0;
..... // sort nosniky[] in ascending order here
for (int i = 0; i < N;) {
int a = nosniky[i];
for (int j = i + 1; j < N;) {
int b = nosniky[j];
for (int m = j + 1; m < N;) {
int c = nosniky[m];
if (a + b > c && a + c > b && c + b > a) {
int temp = jointInts(joinInts(a, b), c);
trojuhelniky[count] = temp;
count ++;
}
while (++m < N && nosniky[m] == c)
; // skip duplicates of the third edge
}
while (++j < N && nosniky[j] == b)
; // skip duplicates of the second edge
}
while (++i < N && nosniky[i] == a)
; // skip duplicates of the first edge
}
return count;
顺便说一句,一旦你保证nosniky[]
数组已排序,你知道c
不小于a
和 b
.然后,正如@pmg 在评论中指出的那样,三角不等式的测试可以简化为第一次比较,因为剩下的两个肯定是满足的:
if (a + b > c) {
int temp = jointInts(joinInts(a, b), c);
trojuhelniky[count] = temp;
count ++;
}
如果你只需要数三角形就可以了,不需要把它们都收集起来,你可以简化最内层的循环:
for (int m = j + 1; m < N;) {
int c = nosniky[m];
if (a + b > c) {
count ++;
}
while (++m < N && nosniky[m] == c)
; // skip duplicates of the third edge
}
按照 Michael Dorgan 评论中的建议,您可以通过提前终止长度为 c
的搜索来节省一些时间。已知太大:
for (int m = j + 1; m < N;) {
int c = nosniky[m];
if (c >= a + b) // too large
break; // skip the rest
if (a + b > c) {
count ++;
}
while (++m < N && nosniky[m] == c)
; // skip duplicates of the third edge
}
然后下一个条件变成重言式,因为它是前一个条件的否定,因此我们可以去掉它:
for (int m = j + 1; m < N;) {
int c = nosniky[m];
if (c >= a + b) // too large
break; // skip the rest
count ++;
while (++m < N && nosniky[m] == c)
; // skip duplicates of the third edge
}
如果您期望 N
的值非常大, 你也可以尝试通过 c
优化搜索太小的值,例如二分查找。您将需要一个二进制搜索函数,该函数接受一个要搜索的数组、一系列索引和一个目标值,并返回等于或大于目标的第一个值的索引(位置)(如果是,则返回范围的右端)未找到)。
int c_minimal = b - a;
// do binary search for c_minimal
// between indices j+1 (inclusive) and N (exclusive)
int initial_m = search(nosniky, j+1, N, c_minimal);
// start from the first value big enough
for (int m = initial_m; m < N;) {
int c = nosniky[m];
if (c >= a + b) // too large
break; // skip the rest
count ++;
while (++m < N && nosniky[m] == c)
; // skip duplicates of the third edge
}
关于c - 如何优化 "Find all possible triangles without duplicates"代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64917205/
我有一个内部表,里面有 108 个条目。从 9 到 9 个条目重复条目,我想删除这些重复项。由于它们完全相同,我使用了 delete adjacent duplicates from itab com
在 Team Foundation Server (TFS) 中链接两个工作项 (WI) 时,在什么情况下将“Duplicate”和“Duplicate Of”区分为“链接类型”是有意义的? 如何处理
ld: duplicate symbol _velocityX in \ /Users/Student/Library/Developer/Xcode/DerivedData/finalproject
我使用 PHP 和 Mysql。 此 SQL 有效: INSERT INTO products (id, title, description) VALUES (10, 'va
我有一个大数据框 (120000x40),我尝试在每一行中找到重复项并显示它们。这就是我的尝试: 创建数据框 import pandas as pd df = pd.DataFrame({'col1'
我是 mySQL 和 PHP 的新手,请多多包涵。 如果我的查询有重复字段,我该如何做到这一点,检索到的数据将具有重复查询字段的重复数据。 一个例子是这样的: 查询 id = 34, 54, 21,
我一直遇到这个错误,但我无法理解它,因为它提示一个值恰好出现一次。 Exception in thread "main" java.lang.IllegalStateException: Duplic
我有一个带有 Vuejs 和 Laravel 的 Web 应用程序 我想使用 CKEditor 5 我安装了依赖项 npm install --save @ckeditor/ckeditor5-vue
我有一个包含以下数据的 csv 文件: Id,Name,Type,date 1,name1,employee,25/04/2017 2,name2,contrator,26/04/2017 3,nam
import CKEditor from '@ckeditor/ckeditor5-react'; import ClassicEditor from '@ckeditor/ckeditor5-bui
表定义: CREATE TABLE PositionalDataNGS ( Date DATE, Time TIME(3) , X FLOAT(5), Y FLOAT(5), D FLOAT(5) ,
我目前正在做一个项目,我要处理数以千计的数据包。现在,我记录每个数据包的 IP 和 MAC 地址以及一些其他信息。为了存储所有这些,我使用 MySQL 并且我的脚本是用 Node.js 编写的。目前我
I am using MySQL 5.1.56, MyISAM. My table looks like this:我使用的是MySQL 5.1.56,MyISAM。我的桌子是这样的: CR
我是新来的,对 SQL 比较陌生。我有一个类似这样的表: [Pk], [Case_No], [Status], [Open_Date], [Close_Date], [Case_Age], [Repo
为什么会收到此警告? warning No duplicate props allowed react/jsx-no-duplicate-props# 它显示的是第28行,但没有使用 Prop 。 最
是否有任何函数或方法可以在 python 2.7 中递归实现此目的? Input : ['and', ['or', 'P', '-R', 'P'], ['or', '-Q', '-R', 'P']]
我正在分析 hadoop 中的数据。有一些重复条目,其中 A、B 列重复,而 C 列不同。我想要做的是仅识别 A、B 重复项,然后为每个重复项打印出 C 列的不同值。 示例数据: row, data
您好,感谢阅读并可能对我有所帮助 我的问题的简要说明: 我正在将数据从一个 Firebird 数据库复制到另一个(称为 V14),并且我正在使用 IBExpert 来执行此操作。这些表的名称相同并且具
我想制作一张很像下面的图片: 我想使用 seaborn 使图表看起来漂亮,并让我自己以后更容易使用 facetgrids(我有十个不同的数据集,我想在同一个图表中显示。) 我在 seaborn 中找到
我在两列“user_id”和“project_id”上有一个复合唯一键。 当我尝试对单行或多行运行 DELETE 查询时,出现错误。 ERROR 1062: 1062: Duplicate entry
我是一名优秀的程序员,十分优秀!