エラトステネスの篩で素数を取り出す。(C#、Java、JavaScript、PHP、Python3、Ruby)

 2から整数nまでの素数を調べる方法は、それぞれの数値を素因数分解して約数が2つ(1とその数自身)である数を見つけていく方法に加えて、「エラトステネスの篩」という方法があります。

 エラトステネスの篩を使うと、素因数分解で素数を調べていく方法よりも少ない計算量で整数nまでの素数を見つけることが可能です。

素因数分解で素数を調べていく方法の計算量 …… O(n√n)
エラトステネスの篩で素数を調べていく方法の計算量 …… O(nloglogn)

 エラトステネスの篩は、2から整数nの平方根までの整数について、nを越えないような2以上の整数倍の数値を消していき、残った数値が素数になります。

2×2、2×3・・・2×m <= n
3×2、3×3・・・3×m <= n



√n×2、√n×2・・・√n×m <= n

 今回はエラトステネスの篩で素数を求めるコードを、C#、Java、JavaScript、PHP、Python3、Rubyの6言語で書いてみました。

 エラトステネスの篩で素数を調べる手順は、大きく分けて3つの処理になってます。

1.配列の0からnまでの要素として、素数であることを示す値(ここでは1)を入れていきます。正の整数の素数は2以上ですが、言語によっては空の要素があるとエラーが出るので、添字0から要素を入れていきます。
2.エラトステネスの篩を用いて、2以上の添字について、素数でない添字の要素に0を入れていきます。
3.2以上の添字について、要素が1であればその添字を素数として出力します。

C#

using System;
using System.Linq;
using System.Collections.Generic;

public class Test{
    public static void Main(){
        //標準入力から数値を読み込む
        var n = int.Parse(Console.ReadLine().Trim());

        //素数フラグ1を設定
        var num = new List<int>();

        for (int i = 0; i <= n; i++){
            num.Add(1);
        }

        //素数以外のフラグを0にする
        for (int j = 2; j <= Math.Sqrt(n); j++){
            int m = 2;
            while (j * m <= n){
                num[j * m] = 0;
                m += 1;
            }
        }

        //素数のみを出力
        for (int k = 2; k <= n; k++){
            if (num[k] == 1){
                 Console.WriteLine(k);
            }
        }
    }
}

Java

public class Main {
    public static void main(String[] args) throws Exception {
        //標準入力から数値を読み込む
        Scanner scan = new Scanner(System.in);
        var n = Integer.parseInt(scan.nextLine().trim());

        //素数フラグ1を設定
        List<Integer> num = new ArrayList<>();
        for (int i = 0; i <= n; i++){
            num.add(1);
        }

        //素数以外のフラグを0にする
        for(int j = 2; j <= Math.sqrt(n); j++){
            int m = 2;

            while (j * m <= n){
                num.set(j * m, 0);
                m += 1;
            }
        }

        //素数のみを出力
        for (int k = 2; k <= n; k++){

            if (num.get(k) == 1){
                System.out.println(k);
            }
        }
    }
}

JavaScript

process.stdin.resume();
process.stdin.setEncoding('utf8');

var lines = [];
var reader = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});
reader.on('line', (line) => {
  lines.push(line);
});
reader.on('close', () => {
    //標準入力から数値を読み込む
    var n = parseInt(lines[0]);

    //素数フラグ1を設定
    var num = [];

    for (var i = 0; i <= n; i++){
        num[i] = 1;
    }

    //素数以外のフラグを0にする
    for (var j = 2; j <= Math.sqrt(n); j++){
        var m = 2;
        while (j * m <= n){
            num[j * m] = 0;
            m += 1;
        }
    }

    //素数のみを出力
    for (var k = 2; k <= n; k++){
        if (num[k] == 1){
            console.log(k);
       }
    }
});

PHP

<?php
//標準入力から数値を読み込む
$n = trim(fgets(STDIN));

//素数フラグ1を設定
$num = [];

for ($i = 0; $i <= $n; $i++){
    $num[$i] = 1;
}

//素数以外のフラグを0にする
for ($j = 2; $j <= sqrt($n); $j++){
    $m = 2;

    while ($j * $m <= $n){
        $num[$j * $m] = 0;
        $m += 1;
    }
}

//素数のみを出力
for ($k = 2; $k <= $n; $k++){
    if ($num[$k] == 1){
        echo $k."\n";
    }
}
?>

Python3

import math

#標準入力から数値を読み込む
n = int(input().rstrip())

#素数フラグ1を設定
num = []
for i in range(0,n+1):
    num.append(1)

#素数以外のフラグを0にする
for j in range(2, int(math.sqrt(n) + 1)):
    m = 2

    while j * m <= n:
        num[j * m] = 0
        m += 1

#素数のみを出力
for k in range(2, n+1):
    if num[k] == 1:
        print(k)

Ruby

#標準入力から数値を読み込む
n = gets.chomp.to_i

#素数フラグ1を設定
num = []

for i in 0..n
    num[i] = 1
end

#素数以外のフラグを0にする
for j in 2..Math.sqrt(n)
    m = 2
    while j * m <= n
       num[j * m] = 0
       m += 1
    end
end

#素数のみを出力
for k in 2..n
    if num[k] == 1
        puts k
    end
end

にほんブログ村 ゲームブログへ

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする