0とlong変数の間の素数を見つけたいのですが、出力を取得できません。
プログラムは
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication16
{
class Program
{
void prime_num(long num)
{
bool isPrime = true;
for (int i = 0; i <= num; i++)
{
for (int j = 2; j <= num; j++)
{
if (i != j && i % j == 0)
{
isPrime = false;
break;
}
}
if (isPrime)
{
Console.WriteLine ( "Prime:" + i );
}
isPrime = true;
}
}
static void Main(string[] args)
{
Program p = new Program();
p.prime_num (999999999999999L);
Console.ReadLine();
}
}
}
誰でも私を助けて、プログラムで起こりうるエラーを見つけることができますか?
ほぼ最適なトライアル除算ふるいを次のような1つの(長い)行で使用すると、これをより速く行うことができます
_Enumerable.Range(0, Math.Floor(2.52*Math.Sqrt(num)/Math.Log(num))).Aggregate(
Enumerable.Range(2, num-1).ToList(),
(result, index) => {
var bp = result[index]; var sqr = bp * bp;
result.RemoveAll(i => i >= sqr && i % bp == 0);
return result;
}
);
_
ここで使用される素数の近似式は π(x) < 1.26 x / ln(x)
です。 x = sqrt(num)
以下の素数でテストするだけです。
Eratosthenesのふるい は、試行の除算よりも実行時間が非常に複雑であることに注意してください(大きなnum
値、適切に実装されている場合)。
これを試して:
void prime_num(long num)
{
// bool isPrime = true;
for (long i = 0; i <= num; i++)
{
bool isPrime = true; // Move initialization to here
for (long j = 2; j < i; j++) // you actually only need to check up to sqrt(i)
{
if (i % j == 0) // you don't need the first condition
{
isPrime = false;
break;
}
}
if (isPrime)
{
Console.WriteLine ( "Prime:" + i );
}
// isPrime = true;
}
}
奇数の除数を数値の平方根までチェックするだけです。つまり、内側のループを開始する必要があります。
for (int j = 3; j <= Math.Sqrt(i); j+=2) { ... }
また、数が素数でないことが判明したらすぐに関数から抜け出すことができます。これ以上除数を確認する必要はありません(既にそれを行っていることがわかります!)。
これは、numが2より大きい場合にのみ機能します。
No Sqrt
合計を維持することで、Sqrtを完全に回避できます。例えば:
int square_sum=1;
for (int j=3; square_sum<i; square_sum+=4*(j++-1)) {...}
これは、数字の合計1+(3 + 5)+(7 + 9)が一連の奇数の正方形(1,9,25など)を与えるためです。したがって、j
はsquare_sum
の平方根を表します。 square_sum
がi
より小さい場合、j
は平方根より小さくなります。
人々はこれを効率的に行うためのいくつかの構成要素に言及しましたが、実際に作品をまとめる人はいません。 エラトステネスのふるい は良いスタートですが、これを使用すると、制限に達する前にメモリが不足しますlong設定しました。だからと言って、それが役に立たないというわけではありません。ループをしているとき、本当に気にするのは素数です。したがって、ふるいを使用して素因数のベースを作成し、ループ内の素因数を使用してプライマシーの数をテストできます。
ただし、ループを作成するとき、ループ条件でsqrt(i)を使用したくないのは、いくつかの回答が示唆しているためです。あなたと私は、sqrtが「純粋な」関数であり、同じ入力パラメーターが与えられた場合に常に同じ答えを返すことを知っています。残念ながら、コンパイラはそれを知らないため、ループ条件で「<= Math.sqrt(x)」のようなものを使用すると、ループの反復ごとに数値のsqrtを再計算します。
これを避けるには、いくつかの異なる方法があります。ループの前にsqrtを事前計算して、ループ条件で事前に計算された値を使用するか、または他の方向で作業してi<Math.sqrt(x)
をi*i<x
に変更できます。個人的に、私は平方根を事前に計算しました-より明確でおそらく少し速いと思いますが、それはループの反復回数に依存します(i*i
はまだ乗算を実行していることを意味します)ループ)。数回の反復で、i*i
は通常より高速になります。十分な反復を行うと、ループの外側でsqrt
を1回実行する時間よりも、反復ごとのi*i
による損失の方が大きくなります。
それはおそらくあなたが扱っている数字のサイズに十分です-15桁の制限は平方根が7または8桁であることを意味し、かなり合理的な量のメモリに収まります。一方、この範囲の数値を頻繁に処理する場合は、 PollardのアルゴリズムまたはBrentのアルゴリズム など、より洗練されたプライムチェックアルゴリズムの一部を確認することをお勧めします。これらは(やや簡潔に言えば)より複雑ですが、lotが大きい数値の場合は高速です。
さらに大きな数値には他のアルゴリズムもあります( 2次シーブ 、 一般的な数値フィールドシーブ )が、今のところそれらには入りません-それらはもっとたくさんあります複雑で、本当に大きな数値を扱う場合にのみ有用です(GNFSは100桁以上の範囲で有用になり始めます)。
最初のステップ:入力が素数かどうかを調べるための拡張メソッドを書く
public static bool isPrime(this int number ) {
for (int i = 2; i < number; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
2ステップ: 0と入力された数値の間のすべての素数を出力するメソッドを記述します
public static void getAllPrimes(int number)
{
for (int i = 0; i < number; i++)
{
if (i.isPrime()) Console.WriteLine(i);
}
}
EDIT_ADD:ウィルネスが正しければ、プログラムの実行中に質問の目的が素数の連続ストリームを出力することだけであることを確認します(Pause /すべての上限に到達するという重大な希望なしに、一時停止して再開するキー)、コードは上限引数なしで記述され、ループの最初の 'i'の範囲チェックは "true"である必要があります。一方、質問が実際に制限まで素数を印刷したい場合、次のコードは、メモリをまったく使用しないという利点があり、奇数に対してのみ試行除算を使用してより効率的にジョブを実行します(上記のように連続ループに変換することもできます):
static void primesttt(ulong top_number) {
Console.WriteLine("Prime: 2");
for (var i = 3UL; i <= top_number; i += 2) {
var isPrime = true;
for (uint j = 3u, lim = (uint)Math.Sqrt((double)i); j <= lim; j += 2) {
if (i % j == 0) {
isPrime = false;
break;
}
}
if (isPrime) Console.WriteLine("Prime: {0} ", i);
}
}
まず、ループ変数が整数であり、テストされる制限が巨大な長整数であるため、質問コードは出力を生成しません。つまり、ループが内部ループを生成する制限に到達することは不可能ですEDITED:変数 'j'が負の数にループバックします。 'j'変数が-1に戻ると、すべての数値が-1END_EDITで割り切れるため、テストされた数値は素数テストに失敗します。これが修正された場合でも、質問コードは非常に大量の合成数(すべての偶数と奇数の合成物)の64ビット除算をその最上部までの範囲全体で実行するため、出力が非常に遅くなります可能性のある各素数の10の16乗。上記のコードは、計算を奇数のみに制限し、テスト対象の現在の数の平方根までのモジュロ除算のみを制限するため、機能します。
最大10億の素数を表示するには1時間程度かかるため、特に計算が遅くなるにつれて、すべての素数を10,000兆(10の16乗)に表示するのにかかる時間を想像できます。範囲が拡大します。 END_EDIT_ADD
Linqを使用した@SLaksによる1つのライナー(種類)の答えは機能しますが、それは Trial Division の最適化されていないバージョンであるため、実際にはエラトステネスのふるいではありません。奇数の素数は、見つかった基本素数の平方で開始せず、ふるいにかける一番上の数の平方根より大きい基本素数のカリングを停止しません。また、複数のネストされた列挙操作のために非常に遅くなります。
実際には、Linq Aggregateメソッドの不正使用であり、生成された2つのLinq Rangeの最初の1つを効果的に使用しません。次のように、列挙オーバーヘッドが少ない最適化された試験部門になります。
static IEnumerable<int> primes(uint top_number) {
var cullbf = Enumerable.Range(2, (int)top_number).ToList();
for (int i = 0; i < cullbf.Count; i++) {
var bp = cullbf[i]; var sqr = bp * bp; if (sqr > top_number) break;
cullbf.RemoveAll(c => c >= sqr && c % bp == 0);
} return cullbf; }
sLaksの回答よりも何倍も高速に実行されます。ただし、リストの生成、複数の列挙、および複数の除算(モジュロによって暗示される)操作のために、依然として低速でメモリ集約型です。
次の真のSieve of Eratosthenes実装は、約30倍高速で実行され、ふるいにかけられた数ごとに1ビット表現のみを使用し、列挙を最終的な反復子シーケンス出力に制限し、奇数の複合体のみを処理する最適化を行うため、メモリを大幅に削減します。次のように、ベースプライムのベースプライムの平方から最大数の平方根までのみカリングします。
static IEnumerable<uint> primes(uint top_number) {
if (top_number < 2u) yield break;
yield return 2u; if (top_number < 3u) yield break;
var BFLMT = (top_number - 3u) / 2u;
var SQRTLMT = ((uint)(Math.Sqrt((double)top_number)) - 3u) / 2u;
var buf = new BitArray((int)BFLMT + 1,true);
for (var i = 0u; i <= BFLMT; ++i) if (buf[(int)i]) {
var p = 3u + i + i; if (i <= SQRTLMT) {
for (var j = (p * p - 3u) / 2u; j <= BFLMT; j += p)
buf[(int)j] = false; } yield return p; } }
上記のコードは、Intel i7-2700K(3.5 GHz)で約77ミリ秒で1,000万の範囲までのすべての素数を計算します。
次のように、usingステートメントと静的Mainメソッドを使用して、2つの静的メソッドのいずれかを呼び出してテストできます。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
static void Main(string[] args) {
Console.WriteLine("This program generates prime sequences.\r\n");
var n = 10000000u;
var elpsd = -DateTime.Now.Ticks;
var count = 0; var lastp = 0u;
foreach (var p in primes(n)) { if (p > n) break; ++count; lastp = (uint)p; }
elpsd += DateTime.Now.Ticks;
Console.WriteLine(
"{0} primes found <= {1}; the last one is {2} in {3} milliseconds.",
count, n, lastp,elpsd / 10000);
Console.Write("\r\nPress any key to exit:");
Console.ReadKey(true);
Console.WriteLine();
}
限界までのシーケンス内の素数の数、最後に見つかった素数、およびそれまでの列挙に費やされた時間が表示されます。
EDIT_ADD:ただし、10000兆未満(10の16乗)未満の素数の列挙を生成するには、マルチコア処理を使用したセグメント化されたページ化アプローチが必要ですが、C++および 非常に高度に最適化されたPrimeSieve を使用しても、見つかった素数の数を生成するために400時間を超える時間が必要ですそれらすべてを列挙するのに長いので、1年以上かけて質問に答えることができます。試行された最適化されていないTrial Divisionアルゴリズムを使用してこれを行うには、10から2百万の累乗年(200万のゼロ年)のような最適化されたTrial Divisionアルゴリズムを使用しても、非常に長い時間がかかります! !)。
彼が試してみたとき、彼のデスクトップマシンがただ座って停止したのも不思議ではありません!!!!彼が100万などのより小さな範囲を試していた場合、実装された数秒の範囲でそれでも時間がかかることに気づいたでしょう。
エラトステネスの最後のふるいでさえ、その範囲に約640テラバイトのメモリを必要とするため、ここで投稿するソリューションはそれを削減しません。
そのため、PrimeSieveのようなページセグメント化されたアプローチのみが、指定された範囲でこの種の問題を処理できます。また、スーパーコンピューターにアクセスできない場合、数十万のコア。 END_EDIT_ADD
私の意見かもしれませんが、プログラムには別の重大なエラーがあります(特定の「素数」の質問は別として、完全に回答されています)。
他のレスポンダーと同様に、これは宿題だと思います。これは、(おそらく)開発者になりたいことを示しています。
コードを区分化することを学ぶ必要があります。プロジェクトで常に必要なことではありませんが、その方法を知っておくと便利です。
メソッドprime_num(long num)は、よりわかりやすく、より説明的な名前になります。そして、与えられた数よりも小さいすべての素数を見つけることになっている場合、それらをリストとして返す必要があります。これにより、ディスプレイと機能を簡単に分離できます。
単純に素数を含むIListを返した場合は、メイン関数でそれらを表示するか(おそらく別の外部関数を呼び出してきれいに印刷する)、または以降の計算で使用できます。
したがって、私の最善の推奨事項は次のようなことです。
public void main(string args[])
{
//Get the number you want to use as input
long x = number;//'number' can be hard coded or retrieved from ReadLine() or from the given arguments
IList<long> primes = FindSmallerPrimes(number);
DisplayPrimes(primes);
}
public IList<long> FindSmallerPrimes(long largestNumber)
{
List<long> returnList = new List<long>();
//Find the primes, using a method as described by another answer, add them to returnList
return returnList;
}
public void DisplayPrimes(IList<long> primes)
{
foreach(long l in primes)
{
Console.WriteLine ( "Prime:" + l.ToString() );
}
}
このような散布が不要な場所で仕事をしたとしても、その方法を知っておくと良いでしょう。
宿題のような匂い。私の非常に古いグラフ電卓には、このような主要なプログラムがありました。技術的には、内部ディビジョンチェックループはi ^(1/2)まで実行するだけで済みます。 0とLの間の「すべての」素数を見つける必要がありますか?もう1つの大きな問題は、ループ変数が「int」で入力データが「long」であることです。これにより、オーバーフローが発生し、ループが一度でも実行できなくなります。ループ変数を修正します。
C#の1行コード:-
Console.WriteLine(String.Join(Environment.NewLine,
Enumerable.Range(2, 300)
.Where(n => Enumerable.Range(2, (int)Math.Sqrt(n) - 1)
.All(nn => n % nn != 0)).ToArray()));
上記の エラトステネスのふるい の答えはまったく正しくありません。書かれているように、1から1000000までのすべての素数を検索します。1からnumまでのすべての素数を検索するには、以下を使用します。
_private static IEnumerable Primes01(int num)
{
return Enumerable.Range(1, Convert.ToInt32(Math.Floor(Math.Sqrt(num))))
.Aggregate(Enumerable.Range(1, num).ToList(),
(result, index) =>
{
result.RemoveAll(i => i > result[index] && i%result[index] == 0);
return result;
}
);
}
_
このリストには素数の最終リストが含まれるため、集合体のシードは1からnumの範囲でなければなりません。 Enumerable.Range(1, Convert.ToInt32(Math.Floor(Math.Sqrt(num))))
は、シードがパージされる回数です。
ExchangeCore Forums 見つかった素数をファイルに書き込むように見える優れたコンソールアプリケーションがリストされています。その同じファイルを開始点として使用できるため、素数の検索を再開する必要がありません2そして、彼らはそのファイルのダウンロードを1億までの発見されたすべての素数で提供するので、それは良いスタートになるでしょう。
ページ上のアルゴリズムは、いくつかのショートカット(奇数と平方根までのチェックのみ)を使用するため、非常に効率的になり、長い数値を計算できます。
つまり、これは基本的にちょうど2つのタイプミス、1つ、最も不幸なfor (int j = 2; j <= num; j++)
であり、非常に長い間続く1%2,1%3 ... 1%(10^15-1)
の非生産的なテストの理由です。そのため、OPは "any output"を取得しませんでした。 それはj < i;
=代わりに。もう1つのマイナーな比較では、i
は0からではなく2から開始する必要があります。
for( i=2; i <= num; i++ )
{
for( j=2; j < i; j++ ) // j <= sqrt(i) is really enough
....
確かに、28兆プライムのconsole print-outが妥当な時間枠で完了することを合理的に期待することはできません。したがって、問題の本来の意図は、明らかに素数の安定したストリームを出力することでした無期限。したがって、エラトステネスのふるいのsimpleふるいが制限されているため、エラトステネスのふるいの単純な使用を提案するすべてのソリューションはまったくメリットがありません-事前に制限を設定する必要があります。
ここで有効なのは、最適化された試行区分であり、それが見つかったときに素数を保存し、候補の下のすべての数だけでなく素数に対してテストします。
2番目の選択肢は、はるかに優れた複雑さ(つまり、はるかに高速)で、 エラトステネスのセグメント化されたふるい を使用することです。これは増分的で無制限です。
これらのスキームは両方とも素数の二重段階の生成を使用します。1つは素数を生成して保存し、他の段階でテスト(またはふるい分け)で使用され、最初の段階の制限をはるかに超えます(もちろんその正方形の下-最初のステージが自動的に拡張され、2番目のステージがさらに上に移動します)。
私はこれが静かな古い質問であることを知っていますが、ここを読んだ後: エラトステネスWiki
これは、アルゴリズムを理解することから私が書いた方法です:
void SieveOfEratosthenes(int n)
{
bool[] primes = new bool[n + 1];
for (int i = 0; i < n; i++)
primes[i] = true;
for (int i = 2; i * i <= n; i++)
if (primes[i])
for (int j = i * 2; j <= n; j += i)
primes[j] = false;
for (int i = 2; i <= n; i++)
if (primes[i]) Console.Write(i + " ");
}
最初のループでは、ブール値の配列にtrueを入力します。
1は素数ではないため、2番目のforループは2から開始し、素数がまだ変更されていないかどうかを確認し、jのインデックスにfalseを割り当てます。
最後のループは、素数のときに印刷するだけです。
率直に言って、提案された解決策のいくつかは本当に遅いので、悪い提案です。単一の数を素数としてテストするには、除算/モジュロ演算子が必要ですが、範囲を計算する必要はありません。
基本的には、以前に見つかった素数の倍数である数を除外します。これは(定義により)素数ではないためです。
簡単にするため、完全な実装は行いません。これは擬似コードでのアプローチです。 (私のマシンでは、実際の実装は8秒以内にSytem.Int32(2 bilion)のすべての素数を計算します。
public IEnumerable<long> GetPrimes(long max)
{
// we safe the result set in an array of bytes.
var buffer = new byte[long >> 4];
// 1 is not a prime.
buffer[0] = 1;
var iMax = (long)Math.Sqrt(max);
for(long i = 3; i <= iMax; i +=2 )
{
// find the index in the buffer
var index = i >> 4;
// find the bit of the buffer.
var bit = (i >> 1) & 7;
// A not set bit means: prime
if((buffer[index] & (1 << bit)) == 0)
{
var step = i << 2;
while(step < max)
{
// find position in the buffer to write bits that represent number that are not prime.
}
}
// 2 is not in the buffer.
yield return 2;
// loop through buffer and yield return odd primes too.
}
}
ソリューションでは、ビット単位の操作を十分に理解する必要があります。しかし、それは方法であり、方法はより高速です。後で使用するために必要な場合は、結果をディスクに保存することもできます。 17 * 10 ^ 9の数値の結果は1 GBで保護でき、その結果セットの計算には最大約2分かかります。
これは、C#で素数を計算する最も速い方法です。
void PrimeNumber(long number)
{
bool IsprimeNumber = true;
long value = Convert.ToInt32(Math.Sqrt(number));
if (number % 2 == 0)
{
IsprimeNumber = false;
}
for (long i = 3; i <= value; i=i+2)
{
if (number % i == 0)
{
// MessageBox.Show("It is divisible by" + i);
IsprimeNumber = false;
break;
}
}
if (IsprimeNumber)
{
MessageBox.Show("Yes Prime Number");
}
else
{
MessageBox.Show("No It is not a Prime NUmber");
}
}
public static void Main()
{
Console.WriteLine("enter the number");
int i = int.Parse(Console.ReadLine());
for (int j = 2; j <= i; j++)
{
for (int k = 2; k <= i; k++)
{
if (j == k)
{
Console.WriteLine("{0}is prime", j);
break;
}
else if (j % k == 0)
{
break;
}
}
}
Console.ReadLine();
}
Prime Helperの非常に高速な計算
public static class PrimeHelper
{
public static IEnumerable<Int32> FindPrimes(Int32 maxNumber)
{
return (new PrimesInt32(maxNumber));
}
public static IEnumerable<Int32> FindPrimes(Int32 minNumber, Int32 maxNumber)
{
return FindPrimes(maxNumber).Where(pn => pn >= minNumber);
}
public static bool IsPrime(this Int64 number)
{
if (number < 2)
return false;
else if (number < 4 )
return true;
var limit = (Int32)System.Math.Sqrt(number) + 1;
var foundPrimes = new PrimesInt32(limit);
return !foundPrimes.IsDivisible(number);
}
public static bool IsPrime(this Int32 number)
{
return IsPrime(Convert.ToInt64(number));
}
public static bool IsPrime(this Int16 number)
{
return IsPrime(Convert.ToInt64(number));
}
public static bool IsPrime(this byte number)
{
return IsPrime(Convert.ToInt64(number));
}
}
public class PrimesInt32 : IEnumerable<Int32>
{
private Int32 limit;
private BitArray numbers;
public PrimesInt32(Int32 limit)
{
if (limit < 2)
throw new Exception("Prime numbers not found.");
startTime = DateTime.Now;
calculateTime = startTime - startTime;
this.limit = limit;
try { findPrimes(); } catch{/*Overflows or Out of Memory*/}
calculateTime = DateTime.Now - startTime;
}
private void findPrimes()
{
/*
The Sieve Algorithm
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
*/
numbers = new BitArray(limit, true);
for (Int32 i = 2; i < limit; i++)
if (numbers[i])
for (Int32 j = i * 2; j < limit; j += i)
numbers[j] = false;
}
public IEnumerator<Int32> GetEnumerator()
{
for (Int32 i = 2; i < 3; i++)
if (numbers[i])
yield return i;
if (limit > 2)
for (Int32 i = 3; i < limit; i += 2)
if (numbers[i])
yield return i;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
// Extended for Int64
public bool IsDivisible(Int64 number)
{
var sqrt = System.Math.Sqrt(number);
foreach (var prime in this)
{
if (prime > sqrt)
break;
if (number % prime == 0)
{
DivisibleBy = prime;
return true;
}
}
return false;
}
private static DateTime startTime;
private static TimeSpan calculateTime;
public static TimeSpan CalculateTime { get { return calculateTime; } }
public Int32 DivisibleBy { get; set; }
}
class CheckIfPrime
{
static void Main()
{
while (true)
{
Console.Write("Enter a number: ");
decimal a = decimal.Parse(Console.ReadLine());
decimal[] k = new decimal[int.Parse(a.ToString())];
decimal p = 0;
for (int i = 2; i < a; i++)
{
if (a % i != 0)
{
p += i;
k[i] = i;
}
else
p += i;
}
if (p == k.Sum())
{ Console.WriteLine ("{0} is prime!", a);}
else
{Console.WriteLine("{0} is NOT prime", a);}
}
}
}
これもできます:
class Program
{
static void Main(string[] args)
{
long numberToTest = 350124;
bool isPrime = NumberIsPrime(numberToTest);
Console.WriteLine(string.Format("Number {0} is prime? {1}", numberToTest, isPrime));
Console.ReadLine();
}
private static bool NumberIsPrime(long n)
{
bool retVal = true;
if (n <= 3)
{
retVal = n > 1;
} else if (n % 2 == 0 || n % 3 == 0)
{
retVal = false;
}
int i = 5;
while (i * i <= n)
{
if (n % i == 0 || n % (i + 2) == 0)
{
retVal = false;
}
i += 6;
}
return retVal;
}
}
このソリューションは、0〜100のすべての素数を表示します。
int counter = 0;
for (int c = 0; c <= 100; c++)
{
counter = 0;
for (int i = 1; i <= c; i++)
{
if (c % i == 0)
{ counter++; }
}
if (counter == 2)
{ Console.Write(c + " "); }
}
Uは、2つの要素(1つとそれ自体)のみが必要な通常の素数の概念を使用できます。こんな感じで簡単に
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PrimeNUmber
{
class Program
{
static void FindPrimeNumber(long num)
{
for (long i = 1; i <= num; i++)
{
int totalFactors = 0;
for (int j = 1; j <= i; j++)
{
if (i % j == 0)
{
totalFactors = totalFactors + 1;
}
}
if (totalFactors == 2)
{
Console.WriteLine(i);
}
}
}
static void Main(string[] args)
{
long num;
Console.WriteLine("Enter any value");
num = Convert.ToInt64(Console.ReadLine());
FindPrimeNumber(num);
Console.ReadLine();
}
}
}
アルゴリズムを実装するいくつかの非常に最適な方法があります。しかし、数学についてあまり知らず、単に要件として素数の定義に従うだけの場合:1とそれだけで割り切れる数(そしてそれ以外は何もない)、正数のコードを理解するのは簡単です。
public bool IsPrime(int candidateNumber)
{
int fromNumber = 2;
int toNumber = candidateNumber - 1;
while(fromNumber <= toNumber)
{
bool isDivisible = candidateNumber % fromNumber == 0;
if (isDivisible)
{
return false;
}
fromNumber++;
}
return true;
}
すべての数字は1で割り切れるので、2からそれ自体の直前の数字までチェックを開始します。それが基本的な推論です。
非常によく似ています-C#でエラトステネスのふるいを実装する演習から:
public class PrimeFinder
{
readonly List<long> _primes = new List<long>();
public PrimeFinder(long seed)
{
CalcPrimes(seed);
}
public List<long> Primes { get { return _primes; } }
private void CalcPrimes(long maxValue)
{
for (int checkValue = 3; checkValue <= maxValue; checkValue += 2)
{
if (IsPrime(checkValue))
{
_primes.Add(checkValue);
}
}
}
private bool IsPrime(long checkValue)
{
bool isPrime = true;
foreach (long prime in _primes)
{
if ((checkValue % prime) == 0 && prime <= Math.Sqrt(checkValue))
{
isPrime = false;
break;
}
}
return isPrime;
}
}
static void Main(string[] args)
{ int i,j;
Console.WriteLine("prime no between 1 to 100");
for (i = 2; i <= 100; i++)
{
int count = 0;
for (j = 1; j <= i; j++)
{
if (i % j == 0)
{ count=count+1; }
}
if ( count <= 2)
{ Console.WriteLine(i); }
}
Console.ReadKey();
}