4

ユーザー入力に基づいて素数を生成しようとしています。これは私がこれまでに持っているものですが、私はそれを理解できないようです:

Console.Write("Please enter the number of prime numbers you would like to see:");
int numberOfPrimes = Convert.ToInt32(Console.ReadLine());

for (int x = 0; x < numberOfPrimes; x++)
{
    for (int a = 2; a <= x ; ++a)
    {
        bool prime = true;
        for (int b = 2; b < a; ++b)
        {
            if (a % b == 0)
            {
                prime = false;
            }//end if
        }//end double nested for
        if (prime == true)
        {
            Console.WriteLine(a);
        }//end if
    }//end nested for
}//end for
4

7 に答える 7

3

ループ構造を見れば、結果が間違っている理由を簡単に理解できるはずです。手でステップスルーします (それほど時間はかかりません)。

現在の結果を取得している理由は、外側のループ ( x < numberOfPrimes) のすべての反復が結果を生成するわけではないためです。内側のループの構造により、かなりの数の反復がスキップされます。

本当に必要なのは、内側のループを再構築することです。最も内側のループは正常に機能し、素数を検出する必要があります。ただし、2 番目のループでは、まだテストされていない数値のみをテストする必要があります。また、素数が見つかったらループを停止する必要があります。

于 2010-03-10T06:55:46.410 に答える
0

次の素数(x)-は、すべての素数sで割ることができない数であり、s <= sqrt(x)です。だからあなたは次のような機能を使うことができます

public bool CheckAndAddPrime(int number,List<int> primes)
{
    var sqrt = Math.Sqrt(number);
    foreach(var prime in primes)
    {
        if(prime>sqrt) break;
        if(number % prime == 0) return false;    
    }

    primes.Add(number);
    return true;
}

そして、あなたが次のような素数を得ることができるよりも

var primes = new List<int>();
Enumerable.Range(2,int.MaxValue).Where(x => x.CheckAndAddPrime(x,primes)).Take(YouCountOfPrimes);
于 2010-03-10T07:08:51.743 に答える
0
var primes = Enumerable.Range(1, numberOfPrimes )
    .Where(x => x != 1 &&
      !Enumerable.Range2, (int)Math.Sqrt(x)).Any(y => x != y && x % y == 0));

codethinked.comからコピー

static void Main(string[] args)
{
    foreach (int no in get_first_k_primes(10))
    {
        Console.Write(" "+no.ToString() );
    }
}

public static List<int> get_first_k_primes(int k)
{
    var primes = new List<int>();

    primes.Add(2);

    int i  = 3;


    while(primes.Count < k)
    {
        if(is_prime(i))
            primes.Add(i);

        i += 2;
    }

    return primes;
}

public static bool is_prime(int n)
{
    if (n % 2 == 0 && n != 2) return false;

    int m = (int)Math.Ceiling(Math.Sqrt(n));

    for (int i = 3; i < m; i += 2)
    {
        if (n % i == 0) return false;
    }

    return true;
}
于 2010-03-10T07:11:58.033 に答える
0

1. 変数の名前を変更します。

まず、これが宿題である場合、意味のない変数名を使用しているため、悪い点が付けられます (教師が彼の塩の価値がある場合) (はい、numberOfPrimes間違っていて、名前を付ける必要があります) requiredNumberOfPrimes。この変数を見ると、「これはどうですか」と自問します彼は何人欲しいのか、それとも何人見つけたのか?」)。

第二に、どこが間違っているのかを理解するのに役立ちます。変数は、それらが表すものに従って論理的に名前を付ける必要があります。変数が何を表しているのか (例えば a と b) を説明できない場合、それらを使って何をしているのかを説明できない可能性があります。

2. ループを見てください。

for (int x = 0; x < numberOfPrimes; x++)

for ループの構造は(initialise; 'should I continue?'; 'each loop do this'). したがって、あなたのループで

  • numberOfPrimesx が*以上になるまで続けます。
  • ループを通過するたびに、 に 1 を追加しxます。

これでよろしいですか? xあなたが見つけた素数の数を表しているように見えます。では、ループを開始するときではなく、素数を見つけたときにインクリメントしてみませんか?

for (int a = 2; a <= x ; ++a)
for (int b = 2; b < a; ++b)

2 から までの各整数を見ていますx。そして、これらの integers のそれぞれについて、 から 2 までaのすべての整数を見ていますa。これらの整数で何をするつもりですか?

トップレベルのループ (xループ) をループするたびに、ループを最初から開始し、aループをループするたびに、ループを最初からa開始しますb

が 10 の場合x、a を 1 回実行し (a=2)、次に a を再度実行し (a=2、a=3)、次に a を再度実行します (a=2、a=3、a=4)。 )、 それから...

3. 結果をコンソールに書き込むのではなく、収集します。

var primes = new List<int>();

非常に簡単。素数を見つけると、primes.Add(a);. 次に、見つかった素数の数 ( ) がわかります。primes.Count素数のリストを使用して、次の素数を効率的に決定できます。必要に応じて、後でリストを使用できます。

于 2010-03-10T07:46:35.863 に答える
0

ループを整理したら、b < sqrt(a) をチェックするだけで済みます。

于 2010-03-10T06:57:11.320 に答える
0

あなたが探しているのは「エラトステネスのふるい」と呼ばれるものです。私は人の宿題をするのが好きではないので、これが唯一の手がかりになります。このアルゴリズムは、インターネット上で簡単に見つけることができます。

于 2010-03-10T07:01:33.310 に答える