C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++でN以下のすべての素数を出力する方法を解説

問題概要

この問題では、整数Nが与えられ、N以下のすべての素数を出力することが求められます。

入出力例

入力: 10
出力: 2 3 5 7

素数とは

素数とは、1とその数自身でのみ割り切れる正の整数のことです。たとえば、2、3、5、7などが該当します。

単純なアプローチ

最も簡単な方法は、2からNまでの各数値について、それより小さい数で順番に割っていき、どこでも割り切れなければ素数として出力するやり方です。これをNに達するまで繰り返します。ただし、この方法は1つの数を判定するのに大量の除算が必要となるため、効率面で課題があります。

効率的なアプローチ

より効果的なのが、素数判定を「2から√Nまで」の範囲で行う方法です。合成数は必ず√N以下の約数を持つため、そこまで調べれば十分に判定できます。さらに、2と3で割り切れるかを先にチェックしたうえで、6ずつ増やしながら「i」と「i+2」(6k±1の形の数)だけを試すことで、無駄な除算を減らし処理を高速化しています。

C++による実装例

#include <bits/stdc++.h>
using namespace std;
 
bool isPrimeNumber(int n){
    if (n <= 1)
        return false;
    if (n <= 3)
        return true;
    if (n % 2 == 0 || n % 3 == 0)
        return false;
    for (int i = 5; i * i <= n; i = i + 6)
        if (n % i == 0 || n % (i + 2) == 0)
            return false;
    return true;
}
 
void printPrime(int n){
    for (int i = 2; i <= n; i++) {
        if (isPrimeNumber(i))
            cout << i << " ";
    }
}
 
int main(){
    int n = 41;
    cout << n << " 以下の素数は次の通りです\n";
    printPrime(n);
}

コードのポイント

  • isPrimeNumber関数: 素数判定を行います。nが1以下なら素数ではない、2と3は素数、2または3で割り切れる場合は素数ではない、と順に判定します。
  • 6k±1の最適化: 5から開始してiを6ずつ増やしながらiとi+2のみ確認することで、判定回数を大幅に削減しています。
  • printPrime関数: 2からnまでの各数に対して素数判定を行い、素数だけを出力します。

実行結果

41以下の素数は以下の通りです。

2 3 5 7 11 13 17 19 23 29 31 37 41

まとめ

このアルゴリズムの素数判定1回あたりの計算量はO(√N)、全体ではO(N√N)となります。なお、「N以下の素数をすべて列挙する」用途にはエラトステネスの篩(ふるい)を使うとO(N log log N)でより高速に求められるため、Nが大きい場合におすすめです。

  1. 【C++】配列内のすべての素数の積を求める方法

    整数型配列 arr[] が与えられたとき、その配列に含まれるすべての素数を見つけ出し、それらの積を計算するのが本記事のテーマです。素数とは、1とその数自身でしか割り切れない正の整数のことです。たとえば、2、3、5、7、11などが素数に該当します。それでは、次の配列を例に解を求めてみましょう。入力: arr[] = { 11, 20, 31, 4, 5, 6, 70 }出力: 1705説明: 配列内の素数は 11、31、5 の3つであり、その積は 11 × 31 × 5 = 1705 となります。入力: arr[] = { 1, 2, 3, 4, 5, 6, 7 }出力: 210説明: 配列内の

  2. C++で最小ヒープから値x未満のすべてのノードを出力する方法

    この問題では、最小ヒープ(Min Heap)と値xが与えられ、xより小さい値を持つすべてのノードを出力することが求められます。最小ヒープとは、すべての親ノードがその子ノードの値以下となる特殊な二分木です。この性質により、根(ルート)には常にヒープ内の最小値が格納されます。具体例を使って問題を理解しましょう。X = 45出力 − 2 4 7 10 17 22 33 34この問題を解くには、最小ヒープ全体を先行順トラバーサル(前順走査)で探索し、与えられた値xより小さい値を持つノードのみを出力します。アルゴリズムのポイント最小ヒープでは親ノードの値が必ず子ノード以下であるため、あるノードの値がx以