我试图产生质数根据用户的投入。这是我迄今为止,但我只是不能似乎图:

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
有帮助吗?

解决方案

您应该能够明白为什么你的结果是错误的,如果你看一下你的循环结构很容易。通过它们一步手(它不会需要很长时间)。

这是你得到你目前的结果的原因是,没有外环(x < numberOfPrimes)的每次迭代产生的结果 - 它会跳过相当多的迭代,由于路内循环的结构

你真正需要做的是重组的内部循环。您最里面的循环工作正常,并应能发现任何素数。你的第二个循环,但是,应该只测试尚未测试号码。此外,应该停止循环一旦你找到一个素数。

其他提示

您应该构建您的代码更好,它真的很乱你现在做的方式。有如果IsPrime(int x)是素数,否则为假返回true的方法x

然后,生成numberOfPrimes素数,你可以做这样的事情:

for ( int primeCount = 0, currentPrime = 2; primeCount < numberOfPrimes; ++currentPrime )
  if ( IsPrime(currentPrime) )
  {
    // do whatever you want with currentPrime, like print it
    ++primeCount;
  }

或者使用筛埃拉托塞尼,这是更快的方法的

要找出一个数x是素数或没有,尝试所有的2Sqrt(x)之间的其因素。为什么只有Sqrt(x)?因为如果a*b = x,然后x / b = ax / a = b,所以,你会两次检查一切,并检查东西,你不应该,如果你走到x / 2甚至x

所以,如果你想使用IsPrime(x)功能是这样的:

// i <= Sqrt(x) <=> i * i <= x
for ( int i = 2; i * i <= x; ++i )
  if ( x % i == 0 )
    return false;

return true;

但我建议你使用埃拉托色尼的筛子,因为它的速度更快。您还可以优化的东西,所以你不检查偶数,因为偶数从来都不是主要的,除了2(两者以筛网和幼稚的方法)。治疗x = 2时为边缘的情况下,然后开始检查每隔数(3,5,7,9,11等)

你所寻找的被称为“埃拉托色尼的筛。”由于我没有把做人民的功课,这是我想给你的唯一线索。该算法容易地在互联网上找到。

接下来的素数(X) - 是由不能所有素数s为单位devided的数目,是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);
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;
}

1.重命名您的变量。

首先,如果这是家庭作业,你会得到不好的分数(如果你的老师值得他的盐),因为你有毫无意义的变量名(是的,甚至 numberOfPrimes 是错误的,应该命名 requiredNumberOfPrimes. 。当我看到这个变量时,我问自己“这是他想要的数量,还是他已经找到的数量?”)。

其次,它会帮助你了解哪里出了问题。变量应该根据它们所代表的内容进行逻辑命名。如果您无法解释变量代表什么(例如a & b) 那么你可能无法解释你正在用它们做什么。

2.看看你的循环。

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

for循环的结构是 (initialise; 'should I continue?'; 'each loop do this'). 。因此在你的循环中

  • 您将继续直到 x 等于或大于 numberOfPrimes*.
  • 每次执行循环时都会加 1 x.

您确定这是您想要做的吗? x 似乎代表您找到的素数数量。那么为什么不在找到质数时而不是开始循环时增加它呢?

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

您正在查看 2 到 2 之间的每个整数 x, , 包括的。对于每个整数 a, ,您正在查看之间的每个整数 a 和 2 个(含)。你打算用这些整数做什么?

每次你循环你的顶级循环( x 循环),你将开始你的 a 从头开始循环,每次循环时 a 循环你将开始你的 b 从头开始循环。

因此,如果 x 是10,你运行一次(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),您可以使用素数列表来有效地确定下一个素数,并且如果需要,您可以稍后使用该列表。

一旦你得到i将环路整理出来,你只需要检查B'的sqrt(一),任何更高,你会发现其他的因素第一。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top