多么奇怪的限制;2147483742 = 2^31 + 94。
正如其他人所指出的那样,对于一个数字来说,这个小试除以素数很可能足够快。如果不是,您可以尝试 Pollard 的 rho 方法:
/* WARNING! UNTESTED CODE! */
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;
}
调用 as ,此函数返回nrho(n,1)
的(可能是复合的)因子;如果要查找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;
}
我在我的博客上讨论了车轮分解;说明比较长,这里不再赘述。对于适合 a 的整数,long
您不太可能显着改善wheel
上面给出的函数。