我有一个 C 代码,可以将一个数字分解成对(蛮力)。有什么方法可以加快代码速度,尽管提高了 1 毫秒(除了多线程)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
clock_t start, end;
void main() {
int first = 1;
int userInput;
scanf_s("%d", &userInput);
int Two = userInput;
start = clock();
while (first != userInput){
Two = userInput;
while (Two != 0) {
if (Two != 1){
if (first * Two == userInput) {
printf("%d %d\n", first, Two);
}
}
Two--;
}
first++;
}
end = clock();
printf("The above code block was executed in %.4f second(s)\n", ((double)end - start) / ((double)CLOCKS_PER_SEC));
system("PAUSE");
}
可以改进的地方:
该函数
clock
的分辨率非常低,似乎是16ms。这对你的任务来说太粗糙了。内循环是多余的。在外循环中,将数字除以第一个除数,如果余数为零,则找到一对除数。
从最小到最大开始搜索除数是合乎逻辑的。寻找范围内的第一个除数
[1, sqrt(N)]
。找到一个除数后,您可以寻找下一对除数,而不是原始数字,而是已经被除数的数字。尽管需要恢复原始数字的除数对,但这将大大加快该过程。
除数通常不会成对搜索。一个数被分解为素数:整数分解。然后,从简单的开始,您可以构建所有必要的对。这是最快的方法。
例子
f1
原来的videx程序。工作缓慢,因为它会检查直到
N
(我们分解的数字)的所有数字对。复杂性O(N^2)
。几乎所有对都打印了两次。如果N > 46340 (= sqrt(2^31))
由于溢出是错误的。f2
由user419509建议。除以
N
所有数字,最高为sqrt(N)
。复杂性O(sqrt(N))
。N < 2^31
.f3
哈利建议。除以
N
所有奇数直到sqrt(N)
。如果找到一个除数,则按它减少N
并继续搜索。最糟糕的复杂性O(sqrt(N))
。N < 2^32
. 因式分解是在单独的通道中从因式分解进行的。f4
包含最多为 的素数表
2^16
。除以N
所有素数,直到sqrt(N)
.N < 2^32
.f5
轮子分解是否简单
2, 3, 5, 7, 11, 13
。除以N
从“轮”到 的所有数字sqrt(N)
。N < 2^64
.N
该表显示了分解为两个大致相等的素数的乘积时的最差运行时间:那么它不会起作用吗?
的确,在我的情况下,与您的代码不同, a*b 和 b*a 是相同的扩展,并且显示一次。
给你(改变了获取执行时间的方式,因为时钟()不是很准确)