!エラトステネスの櫛はN以下の素数を列挙するアルゴリズムとして知られています。素数を列挙するナイーブな実装を行い、計算量を落としていきながらエラトステネスの櫛を考えてみることにします。次の実装の計算量はO(N2)です。0;}この実装では、2〜Nまでの全ての数iに関して、2〜i-1までの数で割り切れるかどうかを調べています。手元の端末ではNが105のような比較的小さな値でも2秒かかりました。試しにNを106としたら終わりませんでした。次にO(N√N)の実装をしましょう。:変更したのは2行目だけです。この実装では先日のエントリで紹介した知見を利用して、2〜Nまでの全ての数iに関して、iが2〜√iまでの整数で割り切れるかどうかを調べています。先ほどのナイーブな実装に比べるととても速く、Nが105のとき、0.15秒で終わりました。Nが106のときはまだ2.9秒ほどかかるようです。次にエラトステネスの篩の要素を導入してみましょう。素数の整数倍の数は素数ではありません。そのため、素数を見つける度にその整数倍の数が「素数ではない」と記録しておけば将来的にその数の素数判定をする必要がなくなるため無駄な計算が省けそうです。文字通り、探索の候補から「篩い落とす」のです。:この方法にすることによって、Nが106のときでも0.3秒で終わるようになりました。考えてみるとこの実装にも無駄があることが分かります。素数の倍数は予め探索から篩い落とされています。数iに訪れたときにその数がまだ「素数ではない」と判定されていなかったとすると、数iは素数である、と言えます。その数を篩うような約数がなかったからです。そのため数iが素数であるかを改めてチェックする必要もないのです。encyclopediaを参考にしました。アニメーションを使った良質な資料です。合わせてご参照ください)。初めに2からNまでの状態を記録する領域を確保します。2には何も記録されていません。そのため、2を素数とします。将来的に処理するであろう2の整数倍の数は全て素数ではありません。