🙆
【C#アルゴリズム】素数の判定
はじめに
paiza 、アルゴリズムの本で素数の判定アルゴリズムについて学んだのでまとめました。以下に、試し割り法、エラトステネスの篩、フェルマーテストについての特徴と、それぞれのC#コード例を説明します。
1. 試し割り法
特徴
- 簡単さ: 素数判定の基本的な方法。
- 効率: 入力値が大きくなると効率が悪くなりやすい。
- 使いどころ: 比較的小さな数を判定する場合に適している。
アルゴリズム
- 数
が 2 未満なら素数ではない。n -
を 2 からn 以下の整数で割り、割り切れるかを確認。\sqrt{n} - 割り切れた場合、素数ではない。
C# 実装例
private static bool IsPrime(long n)
{
if (n == 1)
{
return false;
}
for (long i = 2; i * i <= n; i++)
{
if (n % i == 0)
{
return false;
}
}
return true;
}
2. エラトステネスの篩
特徴
-
効率:
以下のすべての素数を求めるのに効率的。n - 使いどころ: 一度に多くの素数を列挙する場合に適している。
- メモリ使用量: 大量の数値を扱う場合にはメモリを多く消費する。
アルゴリズム
-
配列
isPrime
を用意し、サイズを (インデックスがN+1 から0 まで使えるように)とする。すべての要素をN true
に初期化する。ただし、isPrime[0]
とisPrime[1]
は最初からfalse
に設定する(0 と 1 は素数ではないため)。 -
整数
をi から2 まで順番に調べる。次の手順を実行する:N -
isPrime[i]
がtrue
である場合、 は素数と判定される。その後、i の倍数であるi を順に調べ、それらに対応する2 \times i, 3 \times i, 4 \times i, \ldots isPrime[j]
(ただし かつj = k \times i )をj \leq N false
にする。
-
C# 実装例
private static bool[] Eratosthenes(int n)
{
bool[] isPrimes = Enumerable.Repeat(true, n + 1).ToArray();
isPrimes[0] = isPrimes[1] = false;
for (int i = 2; i <= n; i++)
{
if (isPrimes[i])
{
for (long j = i * 2; j <= n; j += i)
{
isPrimes[j] = false;
}
}
}
return isPrimes;
}
3. フェルマーテスト
特徴
- 効率: 確率的な判定法として非常に高速。
- リスク: 高確率なだけなので素数でないものが素数と判定されることがある。
- 使いどころ: 大きな数の素数性を迅速にチェックする場合。
アルゴリズム
-
a
を から2 までの整数の中からランダムに選ぶ。N-1 -
N
がa
で割り切れる場合、N
は素数ではないと判定する。 -
をa^{N-1} で割った余りがN ならば、1 N
は素数であると判定し、 でない場合は素数ではないと判定する。1
C# 実装例
private static bool FermatTest(int n)
{
int a = 2;
if (n % a == 0)
{
return false;
}
int fermat = 1;
for (int i = 0; i < n - 1; i++)
{
fermat *= a;
fermat %= n;
}
return fermat == 1 ? true : false;
}
まとめ
方法 | 特徴 | 長所 | 短所 |
---|---|---|---|
試し割り法 | 単純な方法 | 実装が簡単 | 大きな数には非効率 |
エラトステネスの篩 | 複数の素数を効率的に求める方法 | 一度に大量の素数を計算可能 | メモリ使用量が多い |
フェルマーテスト | 確率的な高速判定 | 非常に大きな数にも対応可能 | 誤判定が起こる可能性がある |
おすすめ・参考書籍
問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)
データ構造とアルゴリズム[第2版] (新・情報/通信システム工学)
Discussion