C#Sieve of Eratosthenes

时间:2014-09-06 16:13:31

标签: c# primes

我已经编写了这段代码来查找素数,并且效果很好,但计算速度非常慢......我做错了吗?我知道我可能会以错误的方式做这件事,但请帮助我!非常感谢你!

using System;
using System.Collections.Generic;

namespace Primenumbers
{
    class MainClass
    {
        public static void Main (string[] args)
        {    
            List<int> NoPrime = new List<int>();

            for(int x = 2; x < 10000;x++)
            {
                for(int y = x * 2;y < 10000;y = y + x)
                {    
                    if(!NoPrime.Contains(y))
                    {
                        NoPrime.Add(y);
                    }    
                }    
            }

            for(int z = 2; z < 10000;z++)
            {
                if(!NoPrime.Contains(z))
                {
                    Console.WriteLine(z);
                }
            }
        }
    }
}

修改 这是新代码,我将'List'更改为'HashSet'并添加了一个计数器来获取所有素数的总和。非常感谢所有评论/回答的人,你们真棒!

using System;
using System.Collections.Generic;

class MainClass
{
    public static void Main (string[] args)
    {
        HashSet<int> NoPrime = new HashSet<int>();

        long count = 0;
        int n = 2000000;

        for(int x = 2; x < n;x++)
        {
            for(int y = x * 2;y < n;y = y + x)
            {

            if(!NoPrime.Contains(y))
            {
                NoPrime.Add(y);
            }
        }

        for(int z = 2; z < n;z++)
        {
            if(!NoPrime.Contains(z))
            {
                Console.WriteLine(z);
                count = count + z;
            }
        }

        Console.WriteLine("Sum is: " + count);
    }
}

2 个答案:

答案 0 :(得分:4)

代码的复杂性介于O(n *(n log n))和O(n ^ 3)之间(不完全确定)而不是O(n log log n)(参见Sieve of Eratosthenes: Complexity)。

造成的复杂性更高
  • NoPrime列表中的线性搜索(为复杂性提供额外的n
  • 在外循环中缺少“查找下一个素数”检查 - 因此内部循环的复杂度超过O(log log n)

修复:

根据评论中的建议更改为Dictionary<int,bool>(或者更好的是HashSet<int>),以获得Contains的O(1)复杂度。或者,您可以通过为每个数字分配大数bool来直接实现算法,并标记项true(再次给O(1)检查数字是否为素数。)

在外部循环中添加检查以跳过内部迭代,其中x不是素数。

答案 1 :(得分:0)

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

namespace primefinder2
{
    class Program
    {
        static void Main(string[] args)
        {
            //edited version of Alexander Ameye's code (https://stackoverflow.com/users/4014883/alexander-ameye)
            HashSet<int> NoPrime = new HashSet<int>();
        long count = 0;
        Console.WriteLine("please enter a max search value");
        bool input = int.TryParse(Console.ReadLine(), out int n);
        while (input == false)
        {
            Console.WriteLine($"{input} is not a valid value.\nPlease enter a valid number");
            input = int.TryParse(Console.ReadLine(), out n);

        }
        string name = $"Primes_to_{n}";
        string filename = String.Format("{0:yyyy-MM-dd-hh-mm}__{1}", DateTime.Now, name);
        for (int x = 2; x < n; x++)
        {
            for (int y = x * 2; y < n; y = y + x)
            {

                if (!NoPrime.Contains(y))
                {
                    NoPrime.Add(y);
                }

            }

        }

        for (int z = 2; z < n; z++)
        {
            if (!NoPrime.Contains(z))
            {
                Console.WriteLine(z);
                using (System.IO.StreamWriter file =
        new System.IO.StreamWriter($@"{filename}.csv", true))
                {
                    file.WriteLine(z);
                }
                count = count + z;
            }
        }

        Console.WriteLine($"Sum is: {count}");
        Console.ReadLine();


    }
}
}

我对代码进行了一些轻微编辑,以允许用户确定搜索长度,并将素数写入CSV以供将来参考。 让我知道我是怎么做的,如果有什么我可以修改我的编辑。