通过Eratosthene的Sieve C#生成素数

时间:2016-12-14 00:27:18

标签: c# primes

我正在尝试为项目Euler解决问题3,发现here.我想通过使用Eratosthene的Sieve生成一个Primes列表来解决它(找到here.我远未完成问题,但我遇到了一个小问题......

以下是我为此所做的代码。但是,当我运行此代码时,它会使我的计算机停止运行,并在停止它之前输出2。它显然在运行,但似乎并没有正确运行。在它输出列表之前,它应该让我知道(只是检查挂断是否在输出之前)它已完成分配列表......

如果你不确定发生了什么,你可以给我指点挖掘代码并调试它的不同行吗?我在不同的领域尝试过Console.WriteLine,但它似乎没有响应代码。

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

public class Program
{
    static void Main(string[] args)
    {
        long maxNum = 100;
        double maxSqrt = Math.Floor(Math.Sqrt(maxNum));
        long basePrime;
        // Make a list from 2 to maxNum
        List<long> numberList = new List<long>();
        List<long> sievedList = new List<long>();
        for (long i = 2; i <= maxNum; i++) numberList.Add(i);
        // Evaluate the first number of the list, if it is < maxSqrt skip it, create a list of multiples and Except them from numberList, else, numberList is completely Prime Factors

        foreach (long number in numberList.Skip(1))
        {
            basePrime = numberList[0];
            Console.WriteLine(basePrime);
            while (number < maxSqrt)
                {
                    if (number % basePrime == 0)
                    {
                        sievedList.Add(number);
                    }
                    numberList = numberList.Except(sievedList).ToList();
                    sievedList.Clear();
                }
        }
    Console.WriteLine("Finished Allocating Primes");   
    numberList.ForEach(Console.WriteLine);
    }
}

2 个答案:

答案 0 :(得分:1)

要立即解决问题,请将while更改为if

但是您的代码也存在其他问题。

  • 您的numberedList只是一个从2到maxNum的整数列表,您将使用for循环进行填充。然后,您将遍历列表。只需使用for循环中的计数器即可。为了记录哪些数字是素数,BitArray(Int32, Boolean)效果很好。
  • 这也允许摆脱昂贵的LINQ扩展。当您找到非素数时,只需在BitArray中更改它的索引即可。当您找到素数时,请将其添加到列表中;

答案 1 :(得分:0)

灵感来自: Laziness in Python - Computerphile 我将其翻译为C#:

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

namespace GenertatorTest
{
    class Program
    {
        /// <summary>
        /// Natural Numbers Genarator
        /// </summary>
        /// <param name="first">first number in the sequence</param>
        /// <returns>the sequence: first, first + 1, first + 2, ... ∞</returns>
        static IEnumerable<int> natural(int begin)
        {
            yield return begin;
            foreach (var item in natural(begin + 1))
            {
                yield return item;
            }
        }

        /// <summary>
        /// Primary Numbers Genarator
        /// </summary>
        /// <param name="nums">natural numbers sequence which we want to apply  Eratosthene's Sieve on</param>
        /// <returns>infinite primary numbers sequence</returns>
        static IEnumerable<int> primes(IEnumerable<int> nums)
        {
            int p = nums.ElementAt(0);
            yield return p;
            foreach (var item in primes(nums.Where(x => x % p != 0)))
            {
                yield return item;
            }
        }

        static void Main(string[] args)
        {
            foreach (var item in primes(natural(2)))
            {
                Console.WriteLine(item);
                //it is infinite sequence
                //so you cant just run through. 
                Console.ReadKey();
            }
        }
    }
}

实际上,此守则比您想象的要优雅。我们在这里缺少的唯一语法糖是yield from,似乎在C#中不受支持。