なんて奇妙な制限でしょう。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;
}
この関数はとして呼び出され、 nrho(n,1)
の (場合によっては合成された) 因数を返します。nのすべての要因を見つけたい場合は、ループに入れて繰り返し呼び出します。また、素数チェッカーも必要です。あなたの限界については、基数 2、7、および 61 を使用したラビンミラー検定が正確であり、かなり高速であることが証明されています。素数を使ったプログラミングの詳細については、私のブログを参照してください。
しかし、いずれにせよ、このような小さな制限を考えると、素数による試行除算を使用する方がよいと思います。それ以外のものは、漸近的には速くなる可能性がありますが、実際には遅くなります。
編集:この回答は最近いくつかの賛成票を受け取ったので、2,3,5ホイールでホイール因数分解を行う簡単なプログラムを追加しています。と呼ばれるこのプログラムは、 nwheel(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