33

我想找到 0 和 long 变量之间的质数,但我无法获得任何输出。

该程序是

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

namespace ConsoleApplication16
{
    class Program
    {
        void prime_num(long num)
        {
            bool isPrime = true;
            for (int i = 0; i <= num; i++)
            {
                for (int j = 2; j <= num; j++)
                {
                    if (i != j && i % j == 0)
                    {
                        isPrime = false;
                        break;
                    }
                }
                if (isPrime)
                {
                    Console.WriteLine ( "Prime:" + i );
                }
                isPrime = true;
            }
        }

        static void Main(string[] args)
        {
            Program p = new Program();
            p.prime_num (999999999999999L);
            Console.ReadLine();
        }
    }
}

谁能帮我找出程序中可能出现的错误?

4

28 回答 28

83

您可以在一条(长)行中使用几乎最佳的试验划分筛来更快地完成此操作,如下所示:

Enumerable.Range(0, Math.Floor(2.52*Math.Sqrt(num)/Math.Log(num))).Aggregate(
    Enumerable.Range(2, num-1).ToList(), 
    (result, index) => { 
        var bp = result[index]; var sqr = bp * bp;
        result.RemoveAll(i => i >= sqr && i % bp == 0); 
        return result; 
    }
);

这里使用的素数的近似公式是π(x) < 1.26 x / ln(x)。我们只需要通过不大于 的素数进行测试x = sqrt(num)

请注意,Eratosthenes 的筛子比试除法具有更好的运行时间复杂性(num如果正确实施,对于较大的值应该运行得更快)。

于 2009-10-02T15:17:17.200 回答
25

试试这个:

void prime_num(long num)
{

    // bool isPrime = true;
    for (long i = 0; i <= num; i++)
    {
        bool isPrime = true; // Move initialization to here
        for (long j = 2; j < i; j++) // you actually only need to check up to sqrt(i)
        {
            if (i % j == 0) // you don't need the first condition
            {
                isPrime = false;
                break;
            }
        }
        if (isPrime)
        {
            Console.WriteLine ( "Prime:" + i );
        }
        // isPrime = true;
    }
}
于 2009-10-02T15:18:33.687 回答
10

您只需要检查奇数除数,直到数字的平方根。换句话说,您的内部循环需要开始:

for (int j = 3; j <= Math.Sqrt(i); j+=2) { ... }

一旦发现数字不是素数,您也可以退出该功能,您无需再检查除数(我看到您已经这样做了!)。

这仅在 num 大于 2 时才有效。

无平方

您可以通过保持运行总和来完全避免 Sqrt。例如:

int square_sum=1;
for (int j=3; square_sum<i; square_sum+=4*(j++-1)) {...}

这是因为数字 1+(3+5)+(7+9) 的总和将为您提供一系列奇数平方(1、9、25 等)。因此j表示 的平方根square_sum。只要square_sum小于ij小于平方根。

于 2009-10-02T15:18:56.087 回答
10

人们已经提到了一些有效地做到这一点的构建块,但没有人真正将这些部分组合在一起。Eratosthenes的筛子是一个好的开始,但有了它,你会在达到你设定的极限之前很久就耗尽内存。但这并不意味着它没有用——当你在做你的循环时,你真正关心的是素数除数。因此,您可以首先使用筛子创建素数除数的基数,然后使用循环中的这些数来测试数的素数。

但是,当您编写循环时,您真的不希望我们在循环条件中使用 sqrt(i),正如一些答案所建议的那样。你我都知道 sqrt 是一个“纯”函数,如果给定相同的输入参数,它总是给出相同的答案。不幸的是,编译器不知道这一点,所以如果在循环条件中使用类似 '<=Math.sqrt(x)' 的东西,它会在循环的每次迭代中重新计算数字的 sqrt。

您可以通过几种不同的方式避免这种情况。您可以在循环之前预先计算 sqrt,并在循环条件中使用预先计算的值,或者您可以在另一个方向工作,并更改i<Math.sqrt(x)i*i<x. 就个人而言,我会预先计算平方根——我认为它更清晰,可能更快一些——但这取决于循环的迭代次数(这i*i意味着它仍在循环中进行乘法运算)。只需几次迭代,i*i通常会更快。通过足够的迭代,i*i每次迭代的损失超过了sqrt在循环外执行一次的时间。

对于您要处理的数字的大小,这可能已经足够了——15 位限制意味着平方根是 7 或 8 位,这适合相当合理的内存量。另一方面,如果您想处理这个范围内的数字,您可能需要查看一些更复杂的素数检查算法,例如Pollard 或 Brent 算法。这些更复杂(委婉地说),但对于大量数字来说要快得多。

还有其他算法可以处理更大的数字(二次筛一般数字场筛),但我们暂时不会涉及它们——它们要复杂得多,而且真的只对处理非常大的数字有用( GNFS 开始在 100+ 位范围内有用)。

于 2009-10-02T16:55:02.603 回答
8

第一步:编写扩展方法来判断输入是否为素数

public static bool isPrime(this int number ) {

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

    return true;   
}

第 2 步:编写将打印介于 0 和输入数字之间的所有素数的方法

public static void getAllPrimes(int number)
{
    for (int i = 0; i < number; i++)
    {
        if (i.isPrime()) Console.WriteLine(i);
    }
}
于 2012-04-17T15:50:38.480 回答
7

这可能只是我的看法,但您的程序中还有另一个严重错误(抛开给定的“素数”问题,该问题已得到彻底回答)。

像其他响应者一样,我假设这是家庭作业,这表明您想成为一名开发人员(大概)。

你需要学会划分你的代码。这不是你在项目中总是需要做的事情,但知道如何去做是件好事。

您的方法 prime_num(long num) 可以代表一个更好、更具描述性的名称。如果它应该找到小于给定数字的所有素数,它应该将它们作为列表返回。这样可以更轻松地将显示和功能分开。

如果它只是返回一个包含素数的 IList,那么您可以在主函数中显示它们(可能调用另一个外部函数来漂亮地打印它们)或在后续计算中使用它们。

所以我最好的建议是做这样的事情:

public void main(string args[])
{
    //Get the number you want to use as input
    long x = number;//'number' can be hard coded or retrieved from ReadLine() or from the given arguments

    IList<long> primes = FindSmallerPrimes(number);

    DisplayPrimes(primes);
}

public IList<long> FindSmallerPrimes(long largestNumber)
{
    List<long> returnList = new List<long>();
    //Find the primes, using a method as described by another answer, add them to returnList
    return returnList;
}

public void DisplayPrimes(IList<long> primes)
{
    foreach(long l in primes)
    {
        Console.WriteLine ( "Prime:" + l.ToString() );
    }
}

即使您最终在不需要这种操作的地方工作,知道如何去做也是件好事。

于 2009-10-02T16:32:59.650 回答
7

EDIT_ADD: 如果 Will Ness 是正确的,那么问题的目的只是在程序运行期间输出一个连续的素数流(按 Pause/Break 暂停和任何键重新开始),没有认真的希望每次都能到达那个上限,那么代码应该写成没有上限参数和第一个“i”for循环的“真”范围检查。另一方面,如果问题想要实际打印质数到一个极限,那么下面的代码将更有效地完成这项工作,只对奇数使用试除法,其优点是它根本不使用内存(也可以根据上述转换为连续循环):

static void primesttt(ulong top_number) {
  Console.WriteLine("Prime:  2");
  for (var i = 3UL; i <= top_number; i += 2) {
    var isPrime = true;
    for (uint j = 3u, lim = (uint)Math.Sqrt((double)i); j <= lim; j += 2) {
      if (i % j == 0)  {
        isPrime = false;
        break;
      }
    }
    if (isPrime) Console.WriteLine("Prime:  {0} ", i);
  }
}

首先,问题代码不产生输出,因为它的循环变量是整数,并且测试的限制是一个巨大的长整数,这意味着循环不可能达到产生内部循环的限制编辑: 变量'j'循环回到负数;当“j”变量回到 -1 时,被测试的数字未通过质数测试,因为所有数字都可以被 -1 整除 END_EDIT. 即使纠正了这一点,问题代码也会产生非常慢的输出,因为它被绑定了对非常大量的合数(所有偶数加上奇数的复合数)进行 64 位除法,直到该顶部的整个数字范围对于它可能产生的每个素数,数字 10 的 16 次方。上面的代码之所以有效,是因为它将计算限制为仅奇数,并且只对被测试的当前数字的平方根进行模除法。

将素数显示到十亿需要一个小时左右,因此可以想象将所有素数显示到一万万亿(10 的 16 次方)所需的时间,尤其是在计算速度变慢的情况下随着范围的增加。 END_EDIT_ADD

尽管@SLaks 使用Linq 的一个线性(某种)答案有效,但它并不是真正的Eratosthenes 筛子,因为它只是Trial Division的未优化版本,未优化因为它不会消除奇数素数,不会开始在找到的基本素数的平方处,并且不会停止筛选大于要筛选的顶部数的平方根的基本素数。由于多个嵌套的枚举操作,它也很慢。

它实际上是对 Linq Aggregate 方法的滥用,并没有有效地使用生成的两个 Linq Range 中的第一个。它可以成为一个优化的 Trial Division,枚举开销更少,如下所示:

static IEnumerable<int> primes(uint top_number) {
  var cullbf = Enumerable.Range(2, (int)top_number).ToList();
  for (int i = 0; i < cullbf.Count; i++) {
    var bp = cullbf[i]; var sqr = bp * bp; if (sqr > top_number) break;
    cullbf.RemoveAll(c => c >= sqr && c % bp == 0);
  } return cullbf; }

它的运行速度比 SLaks 答案快很多倍。但是,由于 List 生成和多个枚举以及多个除法(由模隐含)操作,它仍然很慢且内存密集。

以下真正的 Eratosthenes 实现的 Sieve 实现运行速度大约快 30 倍,并且占用的内存少得多,因为它只使用每个筛选的数字的一位表示,并将其枚举限制为最终的迭代器序列输出,以及仅处理奇数复合物的优化,并且仅从基素数的基数的平方中剔除直到最大数的平方根,如下所示:

static IEnumerable<uint> primes(uint top_number) {
  if (top_number < 2u) yield break;
  yield return 2u; if (top_number < 3u) yield break;
  var BFLMT = (top_number - 3u) / 2u;
  var SQRTLMT = ((uint)(Math.Sqrt((double)top_number)) - 3u) / 2u;
  var buf = new BitArray((int)BFLMT + 1,true);
  for (var i = 0u; i <= BFLMT; ++i) if (buf[(int)i]) {
      var p = 3u + i + i; if (i <= SQRTLMT) {
        for (var j = (p * p - 3u) / 2u; j <= BFLMT; j += p)
          buf[(int)j] = false; } yield return p; } }

上面的代码在 Intel i7-2700K (3.5 GHz) 上以大约 77 毫秒计算所有素数到一千万范围内。

可以使用 using 语句和静态 Main 方法调用和测试这两个静态方法中的任何一个,如下所示:

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

static void Main(string[] args) {
  Console.WriteLine("This program generates prime sequences.\r\n");

  var n = 10000000u;

  var elpsd = -DateTime.Now.Ticks;

  var count = 0; var lastp = 0u;
  foreach (var p in primes(n)) { if (p > n) break; ++count; lastp = (uint)p; }

  elpsd += DateTime.Now.Ticks;
  Console.WriteLine(
    "{0} primes found <= {1}; the last one is {2} in {3} milliseconds.",
    count, n, lastp,elpsd / 10000);

  Console.Write("\r\nPress any key to exit:");
  Console.ReadKey(true);
  Console.WriteLine();
}

它将显示序列中的素数数量达到限制,找到的最后一个素数,以及枚举到那个为止所花费的时间。

EDIT_ADD: 但是,为了产生问题所问的少于一万万亿(十次方)的素数的枚举,需要使用多核处理的分段分页方法,但即使使用 C++ 和非常高度优化的 PrimeSieve,这将需要超过 400 小时才能产生找到的素数数量,并且需要数十倍的时间来枚举所有素数,因此需要一年多的时间才能完成问题所要求的事情。尝试使用未优化的试除法算法来做到这一点,即使使用优化的试除法算法,例如在十到百万分之二的幂年(即两百万零年!! !)。

难怪他的台式机在他尝试的时候只是坐着不动!!!!如果他尝试了一个更小的范围,比如一百万,他仍然会发现它在实施时需要几秒钟的范围。

我在这里发布的解决方案也不会削减它,因为即使是最后一个埃拉托色尼筛子,该范围内也需要大约 640 TB 的内存。

这就是为什么只有像 PrimeSieve 这样的页面分段方法才能在完全指定的范围内处理这类问题,甚至需要很长时间,比如几周到几年,除非你可以访问一台超级计算机数十万个核心。 END_EDIT_ADD

于 2013-12-06T10:07:04.363 回答
5

闻起来像更多的家庭作业。我非常古老的图形计算器有一个像这样的主要程序。从技术上讲,内部设计检查循环只需要运行到 i^(1/2)。您是否需要找到 0 和 L 之间的“所有”素数?另一个主要问题是您的循环变量是“int”,而您的输入数据是“long”,这将导致溢出,使您的循环甚至无法执行一次。修复循环变量。

于 2009-10-02T15:12:58.733 回答
2

C# 中的一行代码:-

Console.WriteLine(String.Join(Environment.NewLine, 
    Enumerable.Range(2, 300)
        .Where(n => Enumerable.Range(2, (int)Math.Sqrt(n) - 1)
        .All(nn => n % nn != 0)).ToArray()));                                    
于 2012-11-17T14:48:39.093 回答
2

上面的埃拉托色尼筛法答案并不完全正确。如所写,它将找到 1 到 1000000 之间的所有素数。要找到 1 到 num 之间的所有素数,请使用:

private static IEnumerable Primes01(int num)
{
    return Enumerable.Range(1, Convert.ToInt32(Math.Floor(Math.Sqrt(num))))
        .Aggregate(Enumerable.Range(1, num).ToList(),
        (result, index) =>
            {
                result.RemoveAll(i => i > result[index] && i%result[index] == 0);
                return result;
            }
        );
}

Aggregate 的种子应该在 1 到 num 的范围内,因为这个列表将包含最终的素数列表。Enumerable.Range(1, Convert.ToInt32(Math.Floor(Math.Sqrt(num))))是种子被清除的次数。

于 2012-12-19T20:59:52.090 回答
1

所以这基本上只是两个错别字,一个是最不幸的,for (int j = 2; j <= num; j++)这就是非生产性测试1%2,1%3 ... 1%(10^15-1)持续很长时间的原因,所以 OP 没有得到“任何输出”应该是j < i;相反的。相比之下,另一个较小的问题是i应该从 2 开始,而不是从 0 开始:

for( i=2; i <= num; i++ )
{
    for( j=2; j < i; j++ ) // j <= sqrt(i) is really enough
....

当然,不能合理地期望控制台打印出大约 28 万亿个素数在任何合理的时间范围内完成。所以,这个问题的初衷显然是无限期地打印出源源不断的素数。因此,所有提出简单使用 Eratosthenes 筛的解决方案在这里完全没有优点,因为简单的 Eratosthenes 筛是有界的——必须预先设置一个限制。

在这里可以工作的是优化的试验部门,它将在找到素数时保存它们,并针对素数进行测试,而不仅仅是候选者以下的所有数字。

第二种选择,具有更好的复杂性(即更快)是使用Eratosthenes 的分段筛。这是增量和无限的。

这两种方案都将使用双阶段生成素数:一个会生成并保存素数,以供测试(或筛选)的另一阶段使用,远高于第一阶段的限制(当然低于其平方 - 自动扩展第一阶段,因为第二阶段会越来越高)。

于 2012-04-18T22:08:56.300 回答
1

ExchangeCore 论坛列出了一个很好的控制台应用程序,它看起来将找到的素数写入文件,看起来您也可以使用同一个文件作为起点,因此您不必从 2 重新开始查找素数,它们提供了该文件包含所有找到的素数高达 1 亿个,所以这将是一个好的开始。

页面上的算法还采用了一些快捷方式(奇数,只检查平方根),这使得它非常有效,它可以让你计算长数字。

于 2012-07-23T01:44:17.697 回答
1

坦率地说,一些建议的解决方案真的很慢,因此是不好的建议。要测试单个数字是否为素数,您需要一些除法/取模运算符,但对于计算范围,您不必这样做。

基本上你只是排除了早期发现的素数的倍数,因为它们(根据定义)不是素数本身。

我不会给出完整的实现,因为这很容易,这是伪代码的方法。(在我的机器上,实际实现会在 8 秒内计算出 Sytem.Int32(20 亿)中的所有素数。

public IEnumerable<long> GetPrimes(long max)
{
    // we safe the result set in an array of bytes.
    var buffer = new byte[long >> 4];
    // 1 is not a prime.
    buffer[0] = 1;

    var iMax = (long)Math.Sqrt(max);

    for(long i = 3; i <= iMax; i +=2 )
    {
        // find the index in the buffer
        var index = i >> 4;
        // find the bit of the buffer.
        var bit = (i >> 1) & 7;

        // A not set bit means: prime
        if((buffer[index] & (1 << bit)) == 0)
        {
            var step = i << 2;
            while(step < max)
            {
                // find position in the buffer to write bits that represent number that are not prime.
            }
        }
        // 2 is not in the buffer.
        yield return 2;

        // loop through buffer and yield return odd primes too.
    }
}

该解决方案需要对按位运算有很好的理解。但它的方式,而且方式更快。如果您需要它们以供以后使用,您还可以将结果的结果保存在光盘上。17 * 10^9 个数字的结果可以用 1 GB 保护,并且该结果集的计算最多需要大约 2 分钟。

于 2015-02-10T20:50:21.150 回答
1

我知道这是一个安静的老问题,但在这里阅读后: Eratosthenes Wiki 筛

这是我从理解算法中编写它的方式:

void SieveOfEratosthenes(int n)
{
    bool[] primes = new bool[n + 1];

    for (int i = 0; i < n; i++)
        primes[i] = true;

    for (int i = 2; i * i <= n; i++)
        if (primes[i])
            for (int j = i * 2; j <= n; j += i)
                primes[j] = false;

    for (int i = 2; i <= n; i++)
        if (primes[i]) Console.Write(i + " ");
}

在第一个循环中,我们用 true 填充布尔数组。

第二个 for 循环将从 2 开始,因为 1 不是质数,并且将检查质数是否仍然没有改变,然后将 false 分配给 j 的索引。

最后一个循环我们只是在它是素数时打印。

于 2017-05-11T15:03:59.553 回答
0

非常相似 - 从一个练习到在 C# 中实现 Eratosthenes 筛子:

public class PrimeFinder
{
    readonly List<long> _primes = new List<long>();

    public PrimeFinder(long seed)
    {
        CalcPrimes(seed);
    }

    public List<long> Primes { get { return _primes; } }

    private void CalcPrimes(long maxValue)
    {
        for (int checkValue = 3; checkValue <= maxValue; checkValue += 2)
        {
            if (IsPrime(checkValue))
            {
                _primes.Add(checkValue);
            }
        }
    }

    private bool IsPrime(long checkValue)
    {
        bool isPrime = true;

        foreach (long prime in _primes)
        {
            if ((checkValue % prime) == 0 && prime <= Math.Sqrt(checkValue))
            {
                isPrime = false;
                break;
            }
        }
        return isPrime;
    }
}
于 2009-10-02T15:52:08.517 回答
0

Prime Helper 非常快速的计算

public static class PrimeHelper
{

    public static IEnumerable<Int32> FindPrimes(Int32 maxNumber)
    {
        return (new PrimesInt32(maxNumber));
    }

    public static IEnumerable<Int32> FindPrimes(Int32 minNumber, Int32 maxNumber)
    {
        return FindPrimes(maxNumber).Where(pn => pn >= minNumber);
    }

    public static bool IsPrime(this Int64 number)
    {
        if (number < 2)
            return false;
        else if (number < 4 )
            return true;

        var limit = (Int32)System.Math.Sqrt(number) + 1;
        var foundPrimes = new PrimesInt32(limit);

        return !foundPrimes.IsDivisible(number);
    }

    public static bool IsPrime(this Int32 number)
    {
        return IsPrime(Convert.ToInt64(number));
    }

    public static bool IsPrime(this Int16 number)
    {
        return IsPrime(Convert.ToInt64(number));
    }

    public static bool IsPrime(this byte number)
    {
        return IsPrime(Convert.ToInt64(number));
    }
}

public class PrimesInt32 : IEnumerable<Int32>
{
    private Int32 limit;
    private BitArray numbers;

    public PrimesInt32(Int32 limit)
    {
        if (limit < 2)
            throw new Exception("Prime numbers not found.");

        startTime = DateTime.Now;
        calculateTime = startTime - startTime;
        this.limit = limit;
        try { findPrimes(); } catch{/*Overflows or Out of Memory*/}

        calculateTime = DateTime.Now - startTime;
    }

    private void findPrimes()
    {
        /*
        The Sieve Algorithm
        http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
        */
        numbers = new BitArray(limit, true);
        for (Int32 i = 2; i < limit; i++)
            if (numbers[i])
                for (Int32 j = i * 2; j < limit; j += i)
                     numbers[j] = false;
    }

    public IEnumerator<Int32> GetEnumerator()
    {
        for (Int32 i = 2; i < 3; i++)
            if (numbers[i])
                yield return i;
        if (limit > 2)
            for (Int32 i = 3; i < limit; i += 2)
                if (numbers[i])
                    yield return i;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    // Extended for Int64
    public bool IsDivisible(Int64 number)
    {
        var sqrt = System.Math.Sqrt(number);
        foreach (var prime in this)
        {
            if (prime > sqrt)
                break;
            if (number % prime == 0)
            {
                DivisibleBy = prime;
                return true;
            }
        }
        return false;
    }

    private static DateTime startTime;
    private static TimeSpan calculateTime;
    public static TimeSpan CalculateTime { get { return calculateTime; } }
    public Int32 DivisibleBy { get; set; }
}
于 2011-08-30T22:57:34.900 回答
0
    public static void Main()
    {  
        Console.WriteLine("enter the number");
        int i = int.Parse(Console.ReadLine());

        for (int j = 2; j <= i; j++)
        {
            for (int k = 2; k <= i; k++)
            {
                if (j == k)
                {
                    Console.WriteLine("{0}is prime", j);

                    break;
                }
                else if (j % k == 0)
                {
                    break;
                }
            }
        }
        Console.ReadLine();          
    }
于 2011-09-12T08:29:35.013 回答
0
static void Main(string[] args)
    {  int i,j;
        Console.WriteLine("prime no between 1 to 100");
    for (i = 2; i <= 100; i++)
    {
        int count = 0;
        for (j = 1; j <= i; j++)
        {

            if (i % j == 0)
            { count=count+1; }
        }

        if ( count <= 2)
        { Console.WriteLine(i); }


    }
    Console.ReadKey();

    }
于 2012-02-09T18:21:36.187 回答
0

U 可以使用正常的素数概念必须只有两个因素(一个和它本身)。所以这样做,简单的方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PrimeNUmber
{
    class Program
    {
        static void FindPrimeNumber(long num)
        {
            for (long i = 1; i <= num; i++)
            {
                int totalFactors = 0;
                for (int j = 1; j <= i; j++)
                {
                    if (i % j == 0)
                    {
                        totalFactors = totalFactors + 1;
                    }
                }
                if (totalFactors == 2)
                {
                    Console.WriteLine(i);
                }
            }
        }

        static void Main(string[] args)
        {
            long num;
            Console.WriteLine("Enter any value");
            num = Convert.ToInt64(Console.ReadLine());
            FindPrimeNumber(num);
            Console.ReadLine();
        }
    }
}
于 2013-03-29T09:47:46.753 回答
0

这是在 C# 中计算素数的最快方法。

   void PrimeNumber(long number)
    {
        bool IsprimeNumber = true;
        long  value = Convert.ToInt32(Math.Sqrt(number));
        if (number % 2 == 0)
        {
            IsprimeNumber = false;
        }
        for (long i = 3; i <= value; i=i+2)
        {             
           if (number % i == 0)
            {

               // MessageBox.Show("It is divisible by" + i);
                IsprimeNumber = false;
                break;
            }

        }
        if (IsprimeNumber)
        {
            MessageBox.Show("Yes Prime Number");
        }
        else
        {
            MessageBox.Show("No It is not a Prime NUmber");
        }
    }
于 2015-07-24T07:06:07.690 回答
0

此解决方案显示 0 到 100 之间的所有素数。

        int counter = 0;
        for (int c = 0; c <= 100; c++)
        {
            counter = 0;
            for (int i = 1; i <= c; i++)
            {
                if (c % i == 0)
                { counter++; }
            }
            if (counter == 2)
            { Console.Write(c + " "); }
        }
于 2016-01-21T20:55:19.233 回答
0
class CheckIfPrime
   {
    static void Main()
      {
          while (true)
        {
            Console.Write("Enter a number: ");
            decimal a = decimal.Parse(Console.ReadLine());
            decimal[] k = new decimal[int.Parse(a.ToString())];
            decimal p = 0;
            for (int i = 2; i < a; i++)
            {
                if (a % i != 0)
                {
                    p += i;
                    k[i] = i;
                }
                else
                    p += i;
            }
            if (p == k.Sum())
               { Console.WriteLine ("{0} is prime!", a);}
            else
               {Console.WriteLine("{0} is NOT prime", a);}

        }
    }

}
于 2019-01-13T20:37:40.463 回答
0

有一些非常优化的方法可以实现该算法。但是,如果您对数学知之甚少,并且只需遵循素数的定义作为要求:一个只能被 1 和自身整除的数字(除此之外),这里有一个简单易懂的正数代码。

public bool IsPrime(int candidateNumber)
{
    int fromNumber = 2;
    int toNumber = candidateNumber - 1;

    while(fromNumber <= toNumber)
    {
        bool isDivisible = candidateNumber % fromNumber == 0;
        if (isDivisible)
        {
            return false;
        }

        fromNumber++;
    }
    return true;
}

由于每个数字都可以被 1 和自身整除,因此我们从 2 开始检查,直到紧接在其前面的数字。这是基本的推理。

于 2019-02-28T17:11:09.703 回答
0

你也可以这样做:

class Program
  {
    static void Main(string[] args)
    {
      long numberToTest = 350124;
      bool isPrime = NumberIsPrime(numberToTest);
      Console.WriteLine(string.Format("Number {0} is prime? {1}", numberToTest, isPrime));
      Console.ReadLine();
    }

    private static bool NumberIsPrime(long n)
    {
      bool retVal = true;

      if (n <= 3)
      {
        retVal = n > 1;
      } else if (n % 2 == 0 || n % 3 == 0)
      {
        retVal = false;
      }

      int i = 5;

      while (i * i <= n)
      {
        if (n % i == 0 || n % (i + 2) == 0)
        {
          retVal = false;
        }
        i += 6;
      }

      return retVal;
    }
  }
于 2019-03-01T13:25:21.423 回答
0

一种更简单的方法,我所做的是检查一个数字是否正好有两个除法因子,这是素数的本质。

    List<int> factorList = new List<int>();
    int[] numArray = new int[] { 1, 0, 6, 9, 7, 5, 3, 6, 0, 8, 1 };

    foreach (int item in numArray)
    {

        for (int x = 1; x <= item; x++)
        {
          //check for the remainder after dividing for each number less that number
            if (item % x == 0)
            {
                factorList.Add(x);
            }
        }
        if (factorList.Count == 2) // has only 2 division factors ; prime number
        {
            Console.WriteLine(item + " is a prime number ");
        }
        else
        {Console.WriteLine(item + " is not a prime number ");}

        factorList = new List<int>(); // reinitialize list
    }
于 2019-10-29T10:07:53.667 回答
0

这是带有单元测试的解决方案:

解决方案:

public class PrimeNumbersKata
    {
        public int CountPrimeNumbers(int n)
        {
            if (n < 0) throw new ArgumentException("Not valide numbre");
            if (n == 0 || n == 1) return 0;
            int cpt = 0;
            for (int i = 2; i <= n; i++)
            {
                if (IsPrimaire(i)) cpt++;
            }
            return cpt;
        }

        private bool IsPrimaire(int number)
        {

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

测试:

[TestFixture]
    class PrimeNumbersKataTest
    {
        private PrimeNumbersKata primeNumbersKata;
        [SetUp]
        public void Init()
        {
            primeNumbersKata = new PrimeNumbersKata();
        }
        [TestCase(1,0)]
        [TestCase(0,0)]
        [TestCase(2,1)]
        [TestCase(3,2)]
        [TestCase(5,3)]
        [TestCase(7,4)]
        [TestCase(9,4)]
        [TestCase(11,5)]
        [TestCase(13,6)]
        public void CountPrimeNumbers_N_AsArgument_returnCountPrimes(int n, int expected)
        {
            //arrange
            //act
            var actual = primeNumbersKata.CountPrimeNumbers(n);
            //assert
            Assert.AreEqual(expected,actual);
        }

        [Test]
        public void CountPrimairs_N_IsNegative_RaiseAnException()
        {
            var ex = Assert.Throws<ArgumentException>(()=> { primeNumbersKata.CountPrimeNumbers(-1); });
            //Assert.That(ex.Message == "Not valide numbre");
             Assert.That(ex.Message, Is.EqualTo("Not valide numbre"));

        }
    }
于 2020-02-28T14:59:03.053 回答
0

在大学里要数一万以内的素数 这样做了,老师有点惊讶,但我通过了考试。朗c#

void Main()
{
    int number=1;
    for(long i=2;i<10000;i++)
    {
        if(PrimeTest(i))
        {
            Console.WriteLine(number+++" " +i);
        }
    }
}

List<long> KnownPrime = new List<long>();
private bool PrimeTest(long i)
{
    if (i == 1) return false;
    if (i == 2)
    {
        KnownPrime.Add(i);
        return true;
    }
    foreach(int k in KnownPrime)
    {
        if(i%k==0)
            return false;
    }
    KnownPrime.Add(i);
    return true;
}
于 2021-01-30T17:49:28.003 回答
0
for (int i = 2; i < 100; i++)
{
    bool isPrimeNumber = true;
    for (int j = 2; j <= i && j <= 100; j++)
    {
        if (i != j && i % j == 0)
        {
            isPrimeNumber = false; break;
        }
    }
    if (isPrimeNumber)
    {
        Console.WriteLine(i);
    }
}
于 2021-12-15T13:08:34.487 回答