1.素数とは何ですか?
自然数のみ1で割り切れると自身も知られている素数は、それは、除数として1と自分自身以外、数について何もありません。
---> 2値の先頭から-1自体で割り切れるこの番号されるべきではありません。
2.方法:
パッケージcn.tust.cycle; / * *出力が50000未満の素数 * * * / パブリック クラスPrimeNumber { 公共 静的 ボイドメイン(文字列[]引数){ ブール = isFlag trueに、 ロングのstartTime = にSystem.currentTimeMillisを(); // 50000番号トラバース するための(int型 ; I <= 50000 I ++のI = 2 ){ // 1つだけであり、それ自体は自然数で除算することができる素数 のために(INT J = 2、J <I、J ++ ){ IF( 0%J == I ){ isFlag =falseに; } } IF(はisFlag == trueに){ のSystem.out.println(I); } isFlag = trueに; } ロング =終了時刻にSystem.currentTimeMillis(); のSystem.out.printlnは( "に要する時間は次のとおりです。" +(endtime- のstartTime)); } }
出力:要する時間である:5637ms
最初は偽isFlag割り当てられている場合、再びサイクルjを実行しないときのモードでときに、特定の分割I jを、即ち、次のサイクルのiが直接行うことができます。
2.最適化1:
パッケージcn.tust.cycle; / * *出力が50000未満の素数 * * * / パブリック クラスPrimeNumber { 公共 静的 ボイドメイン(文字列[]引数){ ブール = isFlag trueに、 ロングのstartTime = にSystem.currentTimeMillisを(); // 50000番号トラバース するための(int型 ; I <= 50000 I ++のI = 2 ){ // 1つだけであり、それ自体は自然数で除算することができる素数 のために(INT J = 2、J <I、J ++ ){ IF( 0%J == I ){ isFlag =falseに; BREAK ; // 最適化1:自然数の唯一の非素数が有効である } } IF(== isFlag trueに){ System.out.printlnは(I); } isFlag = trueに; } ロングのendtime = にSystem.currentTimeMillis( ); のSystem.out.println( "に要する時間である:" +(endtime- のstartTime)); } }
出力:要する時間である:544ms
最適化2:
パッケージcn.tust.cycle; / * *出力が50000未満の素数 * * * / パブリック クラスPrimeNumber { 公共 静的 ボイドメイン(文字列[]引数){ ブール = isFlag trueに、 ロングのstartTime = にSystem.currentTimeMillisを(); // 番号50000を横断 するための(int型 I = 2; I <= 50000; I ++は){ // 素数は1であり、それ自体によってのみ自然数で割り切れる ため(INT J = 2、J <Math.sqrt(I)。 ++ J){ // 最適化2:自然数自体は素数ではなく、素数が有効である のIF(%I J == 0){ isFlag = falseに; BREAK ; // 最適化1:自然数の唯一の非素数が有効である } } IF(== isFlag trueに){ System.out.printlnは(I); } isFlag = trueに; } ロング終了時刻= システム。 ()にcurrentTimeMillisと; のSystem.out.println( "時間が取られている:" +(endtime- のstartTimeを)); } }
出力:要する時間は69秒
なぜ回数内側のループサイクルは、iの平方根に変更されますか?
答え:97が一定回数に除去するとき97、例えば、結果はまた、場合48.5ルートは、2で割った、2-97を軸ので、数48の後に行かないだろうと仮定されていますサイクル数48対の数が1未満2よりも大きい後ので、それに加えて、この得られた数、上方添加の平方根時間の数の平方根である場合、得られた結果であります既にすなわち、除数は、ライン上のループMath.sqrt(I)と同じくらい長いので、ペアの数を持っていました。