C#查找第N个素数

时间:2011-11-28 11:23:14

标签: c# primes

  

可能重复:
  Prime Number Formula

我正在尝试在c#中编写一些代码,它会给我第n个素数但是一旦我的代码超过121作为素数,它就会开始给我错误的数字。

现在这可能是因为我的代码基于错误的算法,但我想在这里问一下,看看我做错了什么。

代码询问第n个素数10001 - 输出:43751(我知道这是错误的)

这里的任何地方都是我的代码。

int[] p;
int x = 0;
p = new int[10002];
for (int i = 0; i < 1000000; i++)
if (i % 2 != 0)
{
    if (i % 3 != 0)
    {
        if (i % 5 != 0)
        {
            if (i % 7 != 0)
            {
                p[x] = i;
                x++;
                if (x == 10001)
                {
                    Console.WriteLine("{0}", i);
                    break;
                }
            }
        }
    }
}

4 个答案:

答案 0 :(得分:5)

这不是Eratosthenes筛子的工作原理,你应该阅读维基百科文章中的这一部分:

  
      
  • 创建从2到n的连续整数列表:(2,3,4,...,n)。
  •   
  • 最初,让p等于2,即第一个素数。
  •   
  • 从p开始,以p为增量进行计数,并在列表中将每个数字标记为大于p本身。这些数字将是2p,3p,4p等;请注意,其中一些可能已被标记。
  •   
  • 在列表中找到未标记的第一个大于p的数字;让p现在等于这个数字(这是下一个素数)。
  •   
  • 如果列表中没有更多未标记的数字,请停止。否则,请从步骤3开始重复。
  •   

所以基本上你认为的限制(121,来自你的评论)只是他们在动画.gif中使用的一个例子。

这是此方法的C#实现:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace sieve
{
    class Program
    {
        static void Main(string[] args)
        {
            int maxprime = int.Parse(args[0]);
            ArrayList primelist = sieve(maxprime);

            foreach (int prime in primelist)
                Console.WriteLine(prime);

            Console.WriteLine("Count = " + primelist.Count);
            Console.ReadLine();
        }

        static ArrayList sieve(int arg_max_prime)
        {
            BitArray al = new BitArray(arg_max_prime, true);

            int lastprime = 1;
            int lastprimeSquare = 1;

            while (lastprimeSquare <= arg_max_prime)
            {
                lastprime++;

                while (!(bool)al[lastprime])
                    lastprime++;

                lastprimeSquare = lastprime * lastprime;

                for (int i = lastprimeSquare; i < arg_max_prime; i += lastprime)
                    if (i > 0)
                        al[i] = false;
            }

            ArrayList sieve_2_return = new ArrayList();

            for (int i = 2; i < arg_max_prime; i++)
                if (al[i])
                    sieve_2_return.Add(i);

            return sieve_2_return;
        }
    }
}

积分转到Rosetta Code

答案 1 :(得分:2)

那是因为你的算法非常破碎 - 当你需要测试所有* 素数小于当前数字时,你只是测试那些不能被2,3,5和7整除的数字

快速阅读Fun With Prime Numbers,其中有一些更直观的查找素数的方法,一般来说,虽然查找素数的算法偏离了Stack Overflow。

(*)实际上你可以测试比这更少的素数,但我的观点是针对有限数量的素数进行测试将不起作用

更新:您的算法不是The Sieve of Eratosthenes,它仅针对与n = 120情况下Sieve相同的数字进行测试。您应该再次阅读维基百科文章的“算法描述”部分。

答案 2 :(得分:0)

您需要将该数字除以所有数字,直到它的平方根。

例如,您需要将100与sqrt(100)= 10分开,如果它不能与之分割,那么它就是一个素数,所以您需要做的只是

for(int i = 2; i <= Math.Sqrt(number); i++)
{
    if(number%i == 0) return false;
}
return true;

答案 3 :(得分:0)

以下代码打印所有素数,直到1000000

        private static void FindPrimeNumber()
        {
            int topNumber = 1000000;
            var numbers = new BitArray(topNumber, true);

            for(int i = 2; i < topNumber; i++)
                if(numbers[i])
                {
                    for(int j = i * 2; j < topNumber; j += i)
                        numbers[j] = false;
                }

            int primes = 0;

            for(int i = 1; i < topNumber; i++)
                if(numbers[i])
                {
                    primes++;
                    Console.Out.WriteLine(i);
                }

            Console.WriteLine();
            Console.Out.WriteLine(primes + " out of " + topNumber + " prime numbers found.");
            Console.ReadLine();
        }