C#のアルゴリズム小さな問題 - 2 - 首相番号を取得

タイトル:(A)は、1〜nのすべての素数する必要があります。

         (B)は、整数の無秩序な配列内のすべての素数を見つけることができます。

これら二つのトピックは、同じソリューションですが、形は少し変更されました。ここでの唯一の(A)(B)と同様に、解決策を示します。

(1)第一の溶液

まず、プライム、素数であるかを理解、また知られている素数は1と自分自身の整数で割り切れます。1,2,3,5,7のように素数です。

素数の概念を理解し、プログラムを書き出すことは非常に簡単です。あれば数xが素数であるかどうかを知るために、そしてちょうど加えて1〜X Xの間のすべての整数を入れて、xで割り切れることができ、そのような数(除くとX 1)は、その後、X(余りが0です)それは、そうでない場合、xが素数である、素数ではありません。これは、はじめから始まるソリューションです。そして、次のように最適化された方法によって異なります。

 

実際には、我々は、1〜xとすべての整数をチェックする必要はありません。単にそれに1〜[ルートX]の数値を確認してください。、乗算の観点から理解することができる理由については、我々が行う部門は、実際には、順番に、乗算です。私たちは、15かどうか例えば素数を決定します。私たちは3、3 * 5 = 15です時間に加えて。したがって、決意3は、別の数5を決定します。だから我々は唯一xは前にもルート後にチェックされている場合、xのルートをチェックする際に、それをxのルートを確認する必要があります。

コード(C#の): 

         プライベート  静的  ボイド  PrintPrimes( INT  N-)
        {

             // すべての素数の間の出力1〜N - 、N-> = 3。。
            Console.Write( " 1 2。  " );
             int型  I、J =  0 ;
             のための  (I =  3 ;私は< N- =; I = I +  2
            {
                 int型  K =( INT )Math.Sqrt(I)
                 のために  (J =  2 J <= K; J ++)
                {
                     IF  ((I J%)==  0
                    {
                         破ります
                    }
                }

                 もし  (J> K)
                {
                    Console.Write(i.ToString()+  " ")。                 }             }         }  


 

増分区間でのループの2である代わりに、私は++ことに注意してください。偶数はなく、ある程度の効率を向上させる素数は、確かではありませんので。

 

(2)第二の溶液

1以来〜Nをインクリメントし、順序付け、そう溶液のような種類があり得るさ:長さnの識別配列を確立し、添字1〜nは、各番号への完全数が素数かどうかが決定されるたびに割り当てその後、リセットフラグ数、素数0、非素数に対応し、そして実際に、いくつかの重複した決意を排除番号1のすべての倍数の位置を特定します。最後に、トラバーサルは、アレイ、すべての素数の出力を識別します。しかし、そうすることのコストは、ロゴなど、いくつかの追加のメモリ・アレイを開くことです。元の配列を保存する必要はありません場合はもちろん、あなたは元の配列を直接操作することができます。

それは良いが、実際には、あまり最初の方法よりも高速に聞こえます。ストップウォッチでの動作時間を見ることで、このソリューションは、データのみの多量にその動作効率が少し途中でよりも高くなるときか、ではありません。私は2つの非常に多くの倍数(循環ステップ2を増加させる方法)ので、それはだと思うので、この方法は、かなりの部分を削除した後、各素数の計算された倍数があり、その後、配列の割り当てを識別するために、また時間がかかります。

コード(C#の):

        プライベート 静的 ボイド PrintPrimes2(int型N)
        { 
            INT []フラグ= 新しい INT [N]。
            int型 J = 2 ;
            以下のためにint型 I = 2 ; iは= N <; iは++ 
            { 
                場合(フラグ[I - 1 ] == 0 
                { 
                    場合(!IsPrime(I))
                    { 
                        フラグ[I - 1 ] = 1 
                    } 

                    場合(iが<= N / 2 
                    { 
                        J = 2 ながら(iはJ <* n)を
                        { 
                            フラグが[iが jで* - 1 ] = 1 
                            J ++ ; 
                        } 
                    } 
                } 
            } 

            のためのint型のk = 1であり; n <Kあり、k ++ 
            { 
                場合(フラグ[K] == 0 
                { 
                    Console.Write((K + 1).ToString()+ "  " )。
                } 
            } 
        } 

        プライベート 静的 ブール IsPrime(INT X)
        { 
            場合(X < 1 
            { 
                スロー 新しい(ArgumentExceptionがを" 1より小さくすることはできません" )。
            } 

            場合(X < 3 
            { 
                戻り 
            } 
            
            {
                 INT K =(INT )Math.Sqrt(X)。
                int型 I = 2 ;
                以下のための式(I ++; iが= Kを< 
                { 
                    場合(Xの%Iの== 0 
                    { 
                        破ります
                    } 
                } 

                もし(I> K)
                { 
                    戻り 
                } 
                
                { 
                    戻り 
                } 
            } 
        }


 (3)第3の方法

あなたは良いプライム事前にライブラリーを構築することができ、そして構築時に整然とさせることが容易である場合。数が素数であるかどうかを判断し、その後、直接バイナリ検索を素早く判断することができます。n個の範囲内の素数を見つけるには、その後、直接取り出したすべてのライブラリの数がn個未満とすることができます。だから、どのようにライブラリプライムを構築するには?

まず、我々は、溶液から知って、数が素数、及び2〜SQRT(n)はモジュロ演算を行うことができるとの間の唯一の整数であるか否かが判定されます。この決意処理効率をさらに向上させることができます。整数3,6,9 2〜SQRT(n)が属し、我々はその後、確かに6と9で割り切れるない、3による整数割り切れないかどうかを判断する必要がある場合を想像し、これらのステップを省略することができます。!私たちは、構築時に使用することができますが素数列構造となっている

、我々はいくつかのよく確立されたシーケンスがあるとします。P1、P2、... PNを

、今、それが素数であるかどうかをPN + 1を判断する、そして唯一の必要性(1、SQRT(PN + 1 ))の範囲内のすべての素数配列の全てではない整数その間、とすることができます。

そして、これは素数のシーケンスP1、P2、... Pnが含まサブセットであり、明らかです!

次のようにライブラリやコードの数は、プライム、プライムシーケンスを設定されています。

2〜numとリターン間の素数のシーケンスを作成する方法。

        静的リスト< INT > CreatePrimes(INT NUM)
        { 
            リスト < INT >素数= 新しい新しいリスト< 整数 > (); 
            primes.Add(2 ); 
            primes.Add(3。 

            のためのINT I = 5 ; I <NUM = ; I + = 2 
            { 
                BOOL isPrime = trueに; 

                // jは1から始まる理由:iが奇数プラス偶数であるので、それだけ、奇数であることができる、それが素数の最初のセットに、2で除算することができない
                 // 要素2が計算されていません
                のためにint型J = 1 ; 素数[J] *素数[J] <= I; ++ J)
                { 
                    場合(I%素数[j] == 0 
                    { 
                        isPrime = 破ります; 
                    } 
                } 

                もし(isPrime)
                { 
                    primes.Add(I)。
                } 
            } 

            戻り素数を、
        }

操作は非常に頻繁に素数を発見された場合はこのように、あなたは保存され、大きな素数配列を構築するために開始することができます。その後、バイナリ検索が素数が素数の時系列を取って、決定されて見つけることも非常に便利です。

素数を見つけるためのアルゴリズムを記述するためにブログを持っても良いですが、参照http://www.cnblogs.com/luluping/archive/2010/03/03/1677552.htmlを

 

最後に、私はint型です、それは、現時点で我々が扱っているされていることを思い出させるしたいと思います、もちろん、あなたはまた、二重、限り変更することができます。しかし、すべての後に、それは範囲を持つことです。あなたがはるかに長いの範囲を超えて、文字列にかなり大きな数を与えると、それを判断する方法?

1.建設自分格納するための新しいデータ構造、特に私は知りません。人々はこれが問題ではないことを私に言ったチップの開発に携わっがありました。

残りを達成するために、操作の独自のメソッドを書く2.、実際には、小学校の分裂を達成するためのコードを記述します。

書くので、私たちがお手伝いします。

 

 

ます。https://www.cnblogs.com/CSharpSPF/archive/2012/04/04/2432105.htmlで再現

おすすめ

転載: blog.csdn.net/weixin_34072159/article/details/93530998