这个奇怪的限制是什么意思; 2147483742 = 2^31 + 94。
正如其他人所指出的,在这么小的数字范围内,通过质数试除法可能已经足够快了。只有当它不够快时,您可以尝试使用Pollard's rho方法:
long rho(n, c) {
long t = 2;
long h = 2;
long d = 1;
while (d == 1) {
t = (t*t + c) % n;
h = (h*h + c) % n;
h = (h*h + c) % n;
d = gcd(t-h, n); }
if (d == n)
return rho(n, c+1);
return d;
}
称为
rho(n,1)
的函数返回一个(可能复合的)因子
n;如果要找到
n的所有因子,将其放入循环中并重复调用。您还需要一个素性检查器;对于您的限制,使用基数2、7和61的Rabin-Miller测试已被证明准确且相当快速。您可以在
我的博客上阅读更多有关使用质数进行编程的信息。
但无论如何,在给定这样一个小限制的情况下,我认为最好使用质数试除法。其他任何方法在渐近意义下可能更快,但实际上更慢。
编辑:由于此答案最近收到了多个赞,因此我正在添加一个简单的程序,它使用2、3、5轮进行轮筛法。称为wheel(n)
的程序按升序打印出n的因子。
long wheel(long n) {
long ws[] = {1,2,2,4,2,4,2,4,6,2,6};
long f = 2; int w = 0;
while (f * f <= n) {
if (n % f == 0) {
printf("%ld\n", f);
n /= f;
} else {
f += ws[w];
w = (w == 10) ? 3 : (w+1);
}
}
printf("%ld\n", n);
return 0;
}
我在我的博客上讨论了轮子分解;由于解释较长,因此我不会在这里重复。对于适合于long
的整数,您很可能无法显着改进上述给出的wheel
函数。
sqrt(2147483742)
以内的所有质数的表格,并逐一尝试它们。这大约有6K个项目。 - Sergey Kalinichenko