• 締切済み

perl で効率の良い素因数分解の方法

以下は、N を素因数分解し、それにかかる時間を表示するプログラムです。 #!/usr/bin/perl -w use Benchmark; print("N=?"); chomp($n=<STDIN>); $start_time=new Benchmark; $i=2; while($i <= $n){ if($n%$i==0){ print("$i、"); $n = $n/$i; }else {$i++; } } $end_time=new Benchmark; $time=timediff($end_time,$start_time); print("このプログラムの実行時間は".timestr($time)."秒です。\n"); 確かに、このプログラムを用いれば、入力した数字を素因数分解し、それにかかった時間を表示させることができます。 しかしこの方法では、数字が大きくなると計算に時間がかかってしまい、効率がかなり悪くなってしまいます。 ヒントだけでも良いので、どなたかもっと効率の良い方法を教えていただけませんか。 よろしくお願い致します。

みんなの回答

  • ramayana
  • ベストアンサー率75% (215/285)
回答No.3

ANo.1さんが紹介しているρ法が、速いし、プログラミングも簡単です。 ただ、Nが素数のときに無限ループに陥るので、素数判定のルーチン(Miller-Rabin法など)と組み合わせて使うことになります。

回答No.2

定石ですけど n の平方根より大きな i を 調べる必要はないです。 平方根より大きな i で割り切れれば、 その商は平方根より小さくなり、 その商で割り切れるはずだからです。 これだけで劇的に速くなりますよ。 後、6以上では 6で割って 1, 5 以外は 素数ではないから、調べる量を 1/3 に出来ます。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

ρ法とか数体ふるい法とかあるけど... とりあえず ・2以外の素数は奇数であることを使うと調べるべき数は半分くらいに減る (2 と 3 以外の素数は 6n±1 と書けることを使えば 1/3 くらいになる) ・while の条件は緩すぎ という指摘だけしておこう.

関連するQ&A

  • 素因数分解のプログラムを作成しました。

    素因数分解のプログラムを作成しました。 なぜか11桁を超えた場合、正しく表示されません!! アドバイス等お願いします。 あと、処理時間も組んでみましたがこちらもうまくいきません。 改善をお願いしますm(_ _)m #include<stdio.h> #include<time.h> void fanction(int); void main(void) { int n; clock_t start_time, end_time; printf("整数を入力してください。\n"); scanf("%d",&n); start_time = clock(); fanction(n); end_time = clock(); printf("\n\n処理時間:%.3f秒\n",(double)(end_time - start_time) / CLOCKS_PER_SEC); return 0; } void fanction(int n) { int m; char c='='; for(m=2;n != 1;m++) { while(n%m == 0) { n = n/m; printf("%c%d",c,m); c='*'; } } }

  • 素因数分解の問題です

    素因数分解の問題です nは2ケタの自然数で n/20 を既約分数にしたとき 分母が5になるという このようなnは全部で何個あるか?? 答えは18となっています やり方を教えてください

  • 素因数分解の問題

    久々に素因数分解の問題を解いてみようとしたところ、いきなり躓いてしまいました。 二桁の整数nに168をかけると、ある数の二乗になりました。この整数nはいくらになるかという問題です。 168を素因数分解し、n×168=n×2^3×3×7となることは分かります。 これから先、どのように組み立てて解けばよいのか分かりません。 解説では、各素数が偶数個になるように解くと書かれており、ある数の二乗になるため、 n=2×3×7×m^2となっていました。 どうしてこのような式なるのですか? A=A^p×b^q×c^rとなっている時、各指数がすべて偶数(2の倍数)なっていれば、Aは何かの二乗になることは確かめてみました。

  • 素因数分解の一意性?????

    m,n,p,qをすべて互いに素な自然数とした時に、 2^n・p^m=q^mにおいて、 素因数分解の一意性より、qは2の倍数である。 素因数分解の一意性ってどういうことなのでしょうか?

  • すごく大きい数を素因数分解する方法について教えてください。

    すごく大きい数を素因数分解する方法について教えてください。 問題:m,nを2以上の整数とする。√2009=m√nのとき、m=(a) n=(b)である この問題の答えがa=49 B=41でした。 解説には√2009=√49×41=7√41と書いてあります。 解き方は、2009が何で割れるか小さい数から順に試すしかないのでしょうか。 なにか早く解く裏ワザなどあったらいいな・・・と思いました。 よろしくお願いします。

  • 素因数分解の問題で…

    素因数分解の問題で… 中学3年の姪っ子に数学を教えています。 市販の問題集で、解説と回答を見てもどうしても分からない問題があるんです。 〈素因数分解の問題〉 Aは100より小さい自然数で、Aに54をかけると自然数の2乗になるという。このような自然数Aは全部で何個あるか。 〈解答・解説〉 54=2×3の3乗=6×3の2乗だから、A=6×Nの2乗の形になればよい。 A〈100だから、 N=1のとき、A=6 N=2のとき、A=24 N=3のとき、A=54 N=4のとき、A=96 したがって、Aは4個 と参考書には記載されています。 解説の「A=6×Nの2乗の形になればよい。」という理屈が分かりません。 姪っ子に教えられなくて困っています…。 どなたか分かりやすく解説して頂けないでしょうか? よろしくお願い致します!

  • 素因数分解の証明問題

    素因数分解の証明問題 証明方法がわかりません。 自然数の素因数分解をn=(P_1)^e_1(p_2)^e_2・・・(p_r)^e_rとする。このとき、 φ(n)=n{1-(1/p_1)}{1-(1/p_2)}・・・{1-(1/p_r)}となることを示せ。 ただし、自然数m,nに対して、gcd(m,n)=1ならば、φ(mn)=φ(m)φ(n)であることを用いよ。 よろしくお願いします。

  • RSA暗号が破れる素因数分解についてです。

    自然数 N を、√N (= Nの平方根)未満の自然数であって、末位の数字が1,3,7,9のもののうち、小さいもの順のものどもで以て、割ってゆき、N を素因数分解する計算の、時間計算量のオーダーは、 どれ位のものでしょうか。

  • RSA暗号解読の素因数分解による方法について。

    下記の通りで正しいでしょうか。: Microsoft Bing AI (= Bing Chat)生成人工知能の回答を、まとめ、且つ、補足しますと、次の通りです。 自然数 N を、√N (= Nの平方根)未満の自然数であって末位の数字が1,3,7,9のもので以て、割ってゆき、N を素因数分解する、という計算の、時間計算量は、O(Nの4乗根)です。 実際には、RSA暗号による暗号文の暗号は、巨大素数を2つ掛け合わせて作りますので、Nの平方根未満の自然数で、末位が1,3,7,9のもので、しかも、大きいもの順に取ったもので順に割っていけば、N の素因数分解は、時間計算量を、それよりも遥かに小さくして済ませらせます。 上記の様に、問題サイズ N に対する、N の4乗根のオーダーの時間を上界(この場合は、自然数の計算ですので上限)とする、普通の割り算の単純作業だけで、つまり、ごくごく短時間に、N の素因数分解が出来てしまいますので、RSA暗号も、いとも簡単に解けてしまう、ということです。

  • 素因数プログラムで、間違えて因数4で割らない

    練習問題 5-15  2以上の数値を入力し、素因数分解した結果を表示しなさい。    疑問ですが、素因数分解なので割る数字は、2.3.5.7.・・・の自分の数字しか割りきれない数字で  割ります。それでは、以下のプログラムはどこでそれを判断しているのでしょか?  4で割ろうとしないのは、どこのプログラムが司っているのでしょうか  もし!見えない取り組みがあれば宜しくお願いします。  以下プログラムです。 1) int n, x; 2) scanf("%d", &n ); 3) for( x = 2 ; n > 1 ; x++ ){ 4) while( ( n % x ) == 0 ){ 5) printf( "%d ", x ); 6) n /= x; } }