【问题标题】:Check if number is prime number检查数字是否为素数
【发布时间】:2013-03-22 12:18:07
【问题描述】:

我想问一下这是否是检查数字是否为素数的正确方法?因为我读到 0 和 1 不是质数。

int num1;

Console.WriteLine("Accept number:");
num1 = Convert.ToInt32(Console.ReadLine());
if (num1 == 0 || num1 == 1)
{
    Console.WriteLine(num1 + " is not prime number");
    Console.ReadLine();
}
else
{
    for (int a = 2; a <= num1 / 2; a++)
    {
        if (num1 % a == 0)
        {
            Console.WriteLine(num1 + " is not prime number");
            return;
        }

    }
    Console.WriteLine(num1 + " is a prime number");
    Console.ReadLine();
}

【问题讨论】:

  • 是的,素数被定义为大于一。
  • would just like to ask if this is a correct way of checking - 是的。也许您想问一下这是否是一种有效的检查方式?
  • 不。简单地说,您可以从 3 开始 a 并将其增加 2 而不是 1(并且句柄 2 作为特殊情况是素数)。但请看这里:en.wikipedia.org/wiki/Sieve_of_Eratosthenes
  • @MatthewWatson 如果想要生成所有质数到某个限制,那么筛子很好,但是要检查一个数是否是质数,它是没用的。
  • @Servy “如果它足够小,它甚至不会低效”是什么意思?如果您筛分到sqrt(n) 以获得试除法所需的素数,如果您避免使用 2、3 甚至 5 的倍数(如果您是进取心的话),那么筛分比不必要的复合除法工作量更大。如果您要筛分到n 以查找n 是否是筛子中的素数,那么您的算法会逐渐变差(并且常数因子也不会让它在小数中获胜)。

标签: c# primes primality-test


【解决方案1】:

这是good example。我把代码放在这里以防万一有一天网站宕机了。

using System;

class Program
{
    static void Main()
    {
    //
    // Write prime numbers between 0 and 100.
    //
    Console.WriteLine("--- Primes between 0 and 100 ---");
    for (int i = 0; i < 100; i++)
    {
        bool prime = PrimeTool.IsPrime(i);
        if (prime)
        {
        Console.Write("Prime: ");
        Console.WriteLine(i);
        }
    }
    //
    // Write prime numbers between 10000 and 10100
    //
    Console.WriteLine("--- Primes between 10000 and 10100 ---");
    for (int i = 10000; i < 10100; i++)
    {
        if (PrimeTool.IsPrime(i))
        {
        Console.Write("Prime: ");
        Console.WriteLine(i);
        }
    }
    }
}

这是包含IsPrime 方法的类:

using System;

public static class PrimeTool
{
    public static bool IsPrime(int candidate)
    {
    // Test whether the parameter is a prime number.
    if ((candidate & 1) == 0)
    {
        if (candidate == 2)
        {
        return true;
        }
        else
        {
        return false;
        }
    }
    // Note:
    // ... This version was changed to test the square.
    // ... Original version tested against the square root.
    // ... Also we exclude 1 at the end.
    for (int i = 3; (i * i) <= candidate; i += 2)
    {
        if ((candidate % i) == 0)
        {
        return false;
        }
    }
    return candidate != 1;
    }
}

【讨论】:

  • OP 只是想检查给定的数字是否是素数,而不是计算两个数字之间的所有素数。
【解决方案2】:
var number;

Console.WriteLine("Accept number:");
number = Convert.ToInt32(Console.ReadLine());

if (IsPrime(number))
{
    Console.WriteLine("It is prime");
}
else
{
    Console.WriteLine("It is not prime");
}       

public static bool IsPrime(int number)
{
    if (number <= 1) return false;
    if (number == 2) return true;
    if (number % 2 == 0) return false;

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

我将number / 2 更改为Math.Sqrt(number) 因为在wikipedia 中,他们说:

此例程包括将 n 除以每个整数 m 小于 1 且小于或等于 n 的平方根。如果结果 这些除法中的任何一个都是整数,则 n 不是素数, 否则它是一个素数。事实上,如果 n = a*b 是复合的(其中 a 和 b ≠

  1. 那么因素之一 a 或 b 最多必然是 n 的平方根

【讨论】:

  • 很好的解决方案。请注意,您每次循环都在重新计算平方根。
  • 考虑三种情况。如果这个数字实际上是素数,那么当你停在天花板或地板上时都没有关系;无论哪种方式,您都将正确推断它是素数。现在假设它是复合的并且是一个完美的正方形。那么天花板和地板是相等的,所以同样,你选择哪一个并不重要,因为它们是相同的。现在假设它是复合的而不是完美的正方形。那么它有一个因子小于它的平方根,所以底数是正确的。无论我们处理这三种情况中的哪一种,您都可以发言。
  • 请注意,这个论点要求我的第二个主张是正确的:对于每个完美的正方形,平方根的天花板和地板都是相等的。如果 Math.Sqrt 曾经说过 10000 的平方根是 99.9999999999999 而不是 100.0000000000000,那么我的说法是错误的,你应该使用上限。是否存在我的索赔错误的情况?
  • 所以让我们考虑一下您的算法效率低下的其他方式。假设您正在检查一个大素数。您首先检查它是否可以被 2 整除。它不是。然后你检查 3。它不是。然后你检查 4。你为什么检查 4?如果它可以被 4 整除,那么它一定已经可以被 2 整除。然后检查 5。然后检查 6。同样,为什么检查 6?如果它可以被 2 和 3 整除,它只能被 6 整除,您已经检查过了。
  • @SonerGönül 这取决于。如果您测试一个数字,找到平方根的素数比简单地进行试除法忽略偶数(2 除外)和 3 的倍数(3 本身除外)要多得多。如果您要测试大量数字,那么获得试验部门的质数绝对值得。
【解决方案3】:

使用 Soner 的例程,但略有不同:我们将运行直到 i 等于 Math.Ceiling(Math.Sqrt(number)),这是天真的解决方案的诀窍:

boolean isPrime(int number)
{
    if (number == 1) return false;
    if (number == 2) return true;

    var limit = Math.Ceiling(Math.Sqrt(number)); //hoisting the loop limit

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

}

【讨论】:

  • 循环中每次都计算平方根?是不是效率低下?
  • @Mangesh 的意思是,for 循环每次在测试每个可能的除数时都会重新计算 Sqrt - 显然优化不会提升常量表达式,因为它不知道 Math.Ceiling 或 @ 987654325@ 计算(想象一下,如果它是 (new Random()).Next(number))所以你应该把它吊出来。
【解决方案4】:

基于@Micheal 的回答,但检查负数并逐步计算平方

    public static bool IsPrime( int candidate ) {
        if ( candidate % 2 <= 0 ) {
            return candidate == 2;
        }
        int power2 = 9;
        for ( int divisor = 3; power2 <= candidate; divisor += 2 ) {
            if ( candidate % divisor == 0 )
                return false;
            power2 += divisor * 4 + 4;
        }
        return true;
    }

【讨论】:

    【解决方案5】:

    这是一个很好的方法。

        static bool IsPrime(int n)
        {
            if (n > 1)
            {
                return Enumerable.Range(1, n).Where(x => n%x == 0)
                                 .SequenceEqual(new[] {1, n});
            }
    
            return false;
        }
    

    编写程序的一种快速方法是:

            for (;;)
            {
                Console.Write("Accept number: ");
                int n = int.Parse(Console.ReadLine());
                if (IsPrime(n))
                {
                    Console.WriteLine("{0} is a prime number",n);
                }
                else
                {
                    Console.WriteLine("{0} is not a prime number",n);
                }
            }
    

    【讨论】:

    • 3年后,你还写for(;;)这样的代码吗?
    • 在给出了批评之后,我会说我喜欢你的解决方案的简洁性。
    • 我不同意@MattRuwe 关于“创建...之间所有数字的列表”的评论。 AFAIK、Range、Where 和 SequenceEqual 通过流式传输序列而不存储除最后读取的元素之外的任何元素来工作。
    • 有趣 - 我不知道 Range、Where 和 SequenceEqual。
    • @Dementic LOL no.
    【解决方案6】:

    在一本书中找到这个例子,并认为这是一个非常优雅的解决方案。

     static void Main(string[] args)
        {
            Console.Write("Enter a number: ");
            int theNum = int.Parse(Console.ReadLine());
    
            if (theNum < 3)  // special case check, less than 3
            {
                if (theNum == 2)
                {
                    // The only positive number that is a prime
                    Console.WriteLine("{0} is a prime!", theNum);
                }
                else
                {
                    // All others, including 1 and all negative numbers, 
                    // are not primes
                    Console.WriteLine("{0} is not a prime", theNum);
                }
            }
            else
            {
                if (theNum % 2 == 0)
                {
                    // Is the number even?  If yes it cannot be a prime
                    Console.WriteLine("{0} is not a prime", theNum);
                }
                else
                {
                    // If number is odd, it could be a prime
                    int div;
    
                    // This loop starts and 3 and does a modulo operation on all
                    // numbers.  As soon as there is no remainder, the loop stops.
                    // This can be true under only two circumstances:  The value of
                    // div becomes equal to theNum, or theNum is divided evenly by 
                    // another value.
                    for (div = 3; theNum % div != 0; div += 2)
                        ;  // do nothing
    
                    if (div == theNum)
                    {
                        // if theNum and div are equal it must be a prime
                        Console.WriteLine("{0} is a prime!", theNum);
                    }
                    else
                    {
                        // some other number divided evenly into theNum, and it is not
                        // itself, so it is not a prime
                        Console.WriteLine("{0} is not a prime", theNum);
                    }
                }
            }
    
            Console.ReadLine();
        }
    

    【讨论】:

      【解决方案7】:
         bool flag = false;
      
      
                  for (int n = 1;n < 101;n++)
                  {
                      if (n == 1 || n == 2)
                      {
                          Console.WriteLine("prime");
                      }
      
                      else
                      {
                          for (int i = 2; i < n; i++)
                          {
                              if (n % i == 0)
                              {
                                  flag = true;
                                  break;
                              }
                          }
                      }
      
                      if (flag)
                      {
                          Console.WriteLine(n+" not prime");
                      }
                      else
                      {
                          Console.WriteLine(n + " prime");
                      }
                       flag = false;
                  }
      
                  Console.ReadLine();
      

      【讨论】:

      • 此代码运行并查找最多为 100 的每个数字是否为质数。这不是这个问题的目标。
      【解决方案8】:

      只有一行代码:

          private static bool primeNumberTest(int i)
          {
              return i > 3 ? ( (Enumerable.Range(2, (i / 2) + 1).Where(x => (i % x == 0))).Count() > 0 ? false : true ) : i == 2 || i == 3 ? true : false;
          }
      

      【讨论】:

      • .Where(x =&gt; (i % x == 0))).Count() &gt; 0 ? false : true 更简洁(和有效)表示为.All(x =&gt; i%x != 0)。此外,? true : false 是不必要的。最后,这不是代码高尔夫。将所有逻辑打包到一行有什么好处?
      【解决方案9】:

      我实现了一种不同的方法来检查素数,因为:

      • 这些解决方案中的大多数都会不必要地反复遍历相同的倍数(例如,它们会检查 5、10 和 15,单个 % x 5 会测试的东西)。
      • A % by 2 将处理所有偶数(所有以 0、2、4、6 或 8 结尾的整数)。
      • 5 的 % 将处理 5 的所有倍数(所有以 5 结尾的整数)。
      • 剩下的就是测试以 1、3、7 或 9 结尾的整数的偶数除法。但美妙的是,我们可以一次增加 10,而不是增加 2,我将演示一个解决方案。
      • 其他算法没有线程化,因此它们没有像我希望的那样充分利用您的内核。
      • 我还需要支持非常大的素数,因此我需要使用 BigInteger 数据类型而不是 int、long 等。

      这是我的实现:

      public static BigInteger IntegerSquareRoot(BigInteger value)
      {
          if (value > 0)
          {
              int bitLength = value.ToByteArray().Length * 8;
              BigInteger root = BigInteger.One << (bitLength / 2);
              while (!IsSquareRoot(value, root))
              {
                  root += value / root;
                  root /= 2;
              }
              return root;
          }
          else return 0;
      }
      
      private static Boolean IsSquareRoot(BigInteger n, BigInteger root)
      {
          BigInteger lowerBound = root * root;
          BigInteger upperBound = (root + 1) * (root + 1);
          return (n >= lowerBound && n < upperBound);
      }
      
      static bool IsPrime(BigInteger value)
      {
          Console.WriteLine("Checking if {0} is a prime number.", value);
          if (value < 3)
          {
              if (value == 2)
              {
                  Console.WriteLine("{0} is a prime number.", value);
                  return true;
              }
              else
              {
                  Console.WriteLine("{0} is not a prime number because it is below 2.", value);
                  return false;
              }
          }
          else
          {
              if (value % 2 == 0)
              {
                  Console.WriteLine("{0} is not a prime number because it is divisible by 2.", value);
                  return false;
              }
              else if (value == 5)
              {
                  Console.WriteLine("{0} is a prime number.", value);
                  return true;
              }
              else if (value % 5 == 0)
              {
                  Console.WriteLine("{0} is not a prime number because it is divisible by 5.", value);
                  return false;
              }
              else
              {
                  // The only way this number is a prime number at this point is if it is divisible by numbers ending with 1, 3, 7, and 9.
                  AutoResetEvent success = new AutoResetEvent(false);
                  AutoResetEvent failure = new AutoResetEvent(false);
                  AutoResetEvent onesSucceeded = new AutoResetEvent(false);
                  AutoResetEvent threesSucceeded = new AutoResetEvent(false);
                  AutoResetEvent sevensSucceeded = new AutoResetEvent(false);
                  AutoResetEvent ninesSucceeded = new AutoResetEvent(false);
                  BigInteger squareRootedValue = IntegerSquareRoot(value);
                  Thread ones = new Thread(() =>
                  {
                      for (BigInteger i = 11; i <= squareRootedValue; i += 10)
                      {
                          if (value % i == 0)
                          {
                              Console.WriteLine("{0} is not a prime number because it is divisible by {1}.", value, i);
                              failure.Set();
                          }
                      }
                      onesSucceeded.Set();
                  });
                  ones.Start();
                  Thread threes = new Thread(() =>
                  {
                      for (BigInteger i = 3; i <= squareRootedValue; i += 10)
                      {
                          if (value % i == 0)
                          {
                              Console.WriteLine("{0} is not a prime number because it is divisible by {1}.", value, i);
                              failure.Set();
                          }
                      }
                      threesSucceeded.Set();
                  });
                  threes.Start();
                  Thread sevens = new Thread(() =>
                  {
                      for (BigInteger i = 7; i <= squareRootedValue; i += 10)
                      {
                          if (value % i == 0)
                          {
                              Console.WriteLine("{0} is not a prime number because it is divisible by {1}.", value, i);
                              failure.Set();
                          }
                      }
                      sevensSucceeded.Set();
                  });
                  sevens.Start();
                  Thread nines = new Thread(() =>
                  {
                      for (BigInteger i = 9; i <= squareRootedValue; i += 10)
                      {
                          if (value % i == 0)
                          {
                              Console.WriteLine("{0} is not a prime number because it is divisible by {1}.", value, i);
                              failure.Set();
                          }
                      }
                      ninesSucceeded.Set();
                  });
                  nines.Start();
                  Thread successWaiter = new Thread(() =>
                  {
                      AutoResetEvent.WaitAll(new WaitHandle[] { onesSucceeded, threesSucceeded, sevensSucceeded, ninesSucceeded });
                      success.Set();
                  });
                  successWaiter.Start();
                  int result = AutoResetEvent.WaitAny(new WaitHandle[] { success, failure });
                  try
                  {
                      successWaiter.Abort();
                  }
                  catch { }
                  try
                  {
                      ones.Abort();
                  }
                  catch { }
                  try
                  {
                      threes.Abort();
                  }
                  catch { }
                  try
                  {
                      sevens.Abort();
                  }
                  catch { }
                  try
                  {
                      nines.Abort();
                  }
                  catch { }
                  if (result == 1)
                  {
                      return false;
                  }
                  else
                  {
                      Console.WriteLine("{0} is a prime number.", value);
                      return true;
                  }
              }
          }
      }
      

      更新:如果您想更快地实现一个带有试除法的解决方案,您可以考虑使用质数缓存。 一个数只有在不能被其他不超过其平方根值的素数整除时才是素数。除此之外,如果您正在处理足够大的值(取自 Rosetta Code,以防网站出现故障),您可以考虑使用 the probabilistic version of the Miller-Rabin primality test 检查数字的素数:

      // Miller-Rabin primality test as an extension method on the BigInteger type.
      // Based on the Ruby implementation on this page.
      public static class BigIntegerExtensions
      {
        public static bool IsProbablePrime(this BigInteger source, int certainty)
        {
          if(source == 2 || source == 3)
            return true;
          if(source < 2 || source % 2 == 0)
            return false;
      
          BigInteger d = source - 1;
          int s = 0;
      
          while(d % 2 == 0)
          {
            d /= 2;
            s += 1;
          }
      
          // There is no built-in method for generating random BigInteger values.
          // Instead, random BigIntegers are constructed from randomly generated
          // byte arrays of the same length as the source.
          RandomNumberGenerator rng = RandomNumberGenerator.Create();
          byte[] bytes = new byte[source.ToByteArray().LongLength];
          BigInteger a;
      
          for(int i = 0; i < certainty; i++)
          {
            do
            {
              // This may raise an exception in Mono 2.10.8 and earlier.
              // http://bugzilla.xamarin.com/show_bug.cgi?id=2761
              rng.GetBytes(bytes);
              a = new BigInteger(bytes);
            }
            while(a < 2 || a >= source - 2);
      
            BigInteger x = BigInteger.ModPow(a, d, source);
            if(x == 1 || x == source - 1)
              continue;
      
            for(int r = 1; r < s; r++)
            {
              x = BigInteger.ModPow(x, 2, source);
              if(x == 1)
                return false;
              if(x == source - 1)
                break;
            }
      
            if(x != source - 1)
              return false;
          }
      
          return true;
        }
      }
      

      【讨论】:

      • 所以你一次增加 10,只检查 10 个中的 4 个。但你可以增加 30,只检查 30 个中的 8 个。当然,8/30 = 4/15 &lt; 4/10。然后是 48/210。
      • 从 7 开始,递增 30。您真正需要从 7 到 36 的哪些数字?这样不是 2,3 或 5 的倍数。只有 8 个。
      • 您每次将八个数字中的每一个都增加 30。请参阅“车轮分解”(尽管 WP 文章的 IMO 写得不好)。还有:stackoverflow.com/a/21310956/849891 -- 2*3*5 = ....
      • 没有限制,但对于快速增长的投资而言,回报正在迅速减少:它是1/2, 2/6, 8/30, 48/210, 480/2310, ... = 0.5, 0.3333, 0.2667, 0.2286, 0.2078, ...,所以收益是50%, 25%, 16.67%, 10%, ...,2x, 4x, 6x, 10x, ... 需要处理更多的数字。如果我们用循环展开来做,这意味着 2x, ..., 10x, ... 代码爆炸。
      • ...所以“投资回报率”是25%, 6.25%, 2.8%, 1%, ...,所以将轮子放大到11 并不会花太多钱。每个圆周轮 PRODUCT(p_i){i=1..n} 包含 PRODUCT(p_i - 1){i=1..n} 尖峰,但在没有复合材料的情况下我们只能达到 (p_(n+1))^2。滚动 100 个素数的轮子,我们只能得到最高到 547^2=299209 的素数,但那个轮子上有 4181833108490708127856970969853073811885209475016770818056714802062057564305290‌348961566798327912719763961768373051814396765475489229643362657214962862299679072‌90044555142202583817713509990400000000000000000000000000000 尖峰。
      【解决方案10】:

      您还可以根据用户找到质数范围,直到给定数字。

      代码:

      class Program
          {
              static void Main(string[] args)
              {
                  Console.WriteLine("Input a number to find Prime numbers\n");
                  int inp = Convert.ToInt32(Console.ReadLine());
                  Console.WriteLine("\n Prime Numbers are:\n------------------------------");
                  int count = 0;
      
                  for (int i = 1; i <= inp; i++)
                  {
                      for (int j = 2; j < i; j++) // j=2 because if we divide any number with 1 the remaider will always 0, so skip this step to minimize time duration.
                      {
                          if (i % j != 0)
                          {
                              count += 1;
                          }
                      }
                      if (count == (i - 2))
                          {
                              Console.Write(i + "\t"); 
                          }
      
                      count = 0;
                  }
      
                  Console.ReadKey();
      
              }
          }
      

      【讨论】:

        【解决方案11】:

        试试这个代码。

        bool isPrimeNubmer(int n)
        {
            if (n == 2 || n == 3) //2, 3 are prime numbers
                return true;
            else if (n % 2 == 0) //even numbers are not prime numbers
                return false;
            else
            {
                int j = 3;
                int k = (n + 1) / 2 ;
        
                while (j <= k)
                {
                    if (n % j == 0)
                        return false;
                    j = j + 2;
                }
                return true;
            }
        }
        

        【讨论】:

        • 1 不是质数
        【解决方案12】:

        我认为这对初学者来说是一种简单的方法:

        using System;
        using System.Numerics;
        public class PrimeChecker
        {
            public static void Main()
            {
            // Input
                Console.WriteLine("Enter number to check is it prime: ");
                BigInteger n = BigInteger.Parse(Console.ReadLine());
                bool prime = false;
        
            // Logic
                if ( n==0 || n==1)
                {
                    Console.WriteLine(prime);
                }
                else if ( n==2 )
                {
                    prime = true;
                    Console.WriteLine(prime);
                }
                else if (n>2)
                {
                    IsPrime(n, prime);
                }
            }
        
            // Method
            public static void IsPrime(BigInteger n, bool prime)
            {
                bool local = false;
                for (int i=2; i<=(BigInteger)Math.Sqrt((double)n); i++)
                {
                    if (n % i == 0)
                    {
                        local = true;
                        break;
                    }
                }
                if (local)
                    {
                        Console.WriteLine(prime);
                    }
                else
                {
                    prime = true;
                    Console.WriteLine(prime);
                }
            }
        }
        

        【讨论】:

        • 最好还添加一个简短的解释代码的作用以及它背后的核心思想是什么——这将使答案对初学者更容易阅读更有用。欢迎来到 StackOverflow!
        【解决方案13】:

        此版本计算素数平方根列表,仅检查是否低于平方根的素数列表,并在列表中使用二进制搜索来查找已知素数。我循环检查前 1,000,000 个素数,大约需要 7 秒。

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;
        
        namespace ConsoleApplication5
        {
            class Program
            {
                static void Main(string[] args)
                {
                    //test();
                    testMax();
                    Console.ReadLine();
                }
        
                static void testMax()
                {
                    List<int> CheckPrimes = Enumerable.Range(2, 1000000).ToList();
                    PrimeChecker pc = new PrimeChecker(1000000);
                    foreach (int i in CheckPrimes)
                    {
                        if (pc.isPrime(i))
                        {
                            Console.WriteLine(i);
                        }
                    }
                }
            }
        
            public class PrimeChecker{
                public List<int> KnownRootPrimesList;
                public int HighestKnownPrime = 3;
        
                public PrimeChecker(int Max=1000000){
                    KnownRootPrimesList = new List<int>();
                    KnownRootPrimesList.Add(2);
                    KnownRootPrimesList.Add(3);
                    isPrime(Max);
                }
        
                public bool isPrime(int value)
                {
                    int srt = Convert.ToInt32(Math.Ceiling(Math.Sqrt(Convert.ToDouble(value))));
                    if(srt > HighestKnownPrime)
                    {
                        for(int i = HighestKnownPrime + 1; i <= srt; i++)
                        {
                            if (i > HighestKnownPrime)
                            {
                                if(isPrimeCalculation(i))
                                {
                                        KnownRootPrimesList.Add(i);
                                        HighestKnownPrime = i;
                                }
                            }
                        }
                    }
                    bool isValuePrime = isPrimeCalculation(value);
                    return(isValuePrime);
                }
        
                private bool isPrimeCalculation(int value)
                {
                    if (value < HighestKnownPrime)
                    {
                        if (KnownRootPrimesList.BinarySearch(value) > -1)
                        {
                            return (true);
                        }
                        else
                        {
                            return (false);
                        }
                    }
                    int srt = Convert.ToInt32(Math.Ceiling(Math.Sqrt(Convert.ToDouble(value))));
                    bool isPrime = true;
                    List<int> CheckList = KnownRootPrimesList.ToList();
                    if (HighestKnownPrime + 1 < srt)
                    {
                        CheckList.AddRange(Enumerable.Range(HighestKnownPrime + 1, srt));
                    }
                    foreach(int i in CheckList)
                    {
                        isPrime = ((value % i) != 0);
                        if(!isPrime)
                        {
                            break;
                        }
                    }
                    return (isPrime);
                }
        
                public bool isPrimeStandard(int value)
                {
                    int srt = Convert.ToInt32(Math.Ceiling(Math.Sqrt(Convert.ToDouble(value))));
                    bool isPrime = true;
                    List<int> CheckList = Enumerable.Range(2, srt).ToList();
                    foreach (int i in CheckList)
                    {
                        isPrime = ((value % i) != 0);
                        if (!isPrime)
                        {
                            break;
                        }
                    }
                    return (isPrime);
                }
            }
        }
        

        【讨论】:

          【解决方案14】:

          函数中的算法包括测试 n 是否是 2 和 sqrt (n) 之间的任何整数的倍数。如果不是,则返回 True,表示数 (n) 是质数,否则返回 False,表示 n 除以 2 和 sqrt(n) 的底整数部分之间的数。

          private static bool isPrime(int n)
                  {
                      int k = 2;
                      while (k * k <= n)
                      {
                          if ((n % k) == 0)
                              return false;
                          else k++;
                      }
                      return true;
                  }
          

          【讨论】:

          • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。也请尽量不要用解释性的 cmets 挤满你的代码,这会降低代码和解释的可读性!
          【解决方案15】:

          这基本上是 Eric Lippert 在上面某处提出的绝妙建议的实现。

              public static bool isPrime(int number)
              {
                  if (number == 1) return false;
                  if (number == 2 || number == 3 || number == 5) return true;
                  if (number % 2 == 0 || number % 3 == 0 || number % 5 == 0) return false;
          
                  var boundary = (int)Math.Floor(Math.Sqrt(number));
          
                  // You can do less work by observing that at this point, all primes 
                  // other than 2 and 3 leave a remainder of either 1 or 5 when divided by 6. 
                  // The other possible remainders have been taken care of.
                  int i = 6; // start from 6, since others below have been handled.
                  while (i <= boundary)
                  {
                      if (number % (i + 1) == 0 || number % (i + 5) == 0)
                          return false;
          
                      i += 6;
                  }
          
                  return true;
              }
          

          【讨论】:

          • 为什么不把循环改成for (int i = 6; i &lt;= boundary; i += 6)
          • 可能将第一行改为if (number &lt;= 1) return false;
          【解决方案16】:

          函数中的算法包括测试 n 是否是 2 和 sqrt (n) 之间的任何整数的倍数。如果不是,则返回 True,表示数 (n) 是质数,否则返回 False,表示 n 除以 2 和 sqrt(n) 的底整数部分之间的数。

          递归版本

                  // Always call it as isPrime(n,2)
                  private static bool isPrime(int n, int k)
                  {
                      if (k * k <= n)
                      {
                          if ((n % k) == 0)
                              return false;
                          else return isPrime(n, k + 1);
                      }
                      else
                          return true;
                  }
          

          【讨论】:

          • 任何大的数字都会导致 StackOverflowExcpetion。
          • 正确。因为递归的深层次。这就是我第一次发布迭代方法的方式。递归是优雅的;)
          【解决方案17】:

          你也可以试试这个:

          bool isPrime(int number)
              {
                  return (Enumerable.Range(1, number).Count(x => number % x == 0) == 2);
              }
          

          【讨论】:

            【解决方案18】:

            质数是大于一且不能为 除 1 和它本身之外的任何其他数。

            @这个程序会告诉你给定的数字是否是素数,并且会告诉你非素数它可以被(一个数字)整除,而不是 1 或它本身?@

                    Console.Write("Please Enter a number: ");
                    int number = int.Parse(Console.ReadLine());
                    int count = 2; 
                    // this is initial count number which is greater than 1
            
                    bool prime = true;
                    // used Boolean value to apply condition correctly
            
                    int sqrtOfNumber = (int)Math.Sqrt(number); 
                    // square root of input number this would help to simplify the looping.  
            
                    while (prime && count <= sqrtOfNumber)
                    {
                        if ( number % count == 0)
                        {
                        Console.WriteLine($"{number} isn't prime and it divisible by 
                                                  number {count}");  // this will generate a number isn't prime and it is divisible by a number which is rather than 1 or itself and this line will proves why it's not a prime number.
                            prime = false;
                        }
                        
                        count++;
                        
                    }
                    if (prime && number > 1)
                    
                    {
                        Console.WriteLine($"{number} is a prime number");
                    }
                    else if (prime == true)
                    // if input is 1 or less than 1 then this code will generate
                    {
                        Console.WriteLine($"{number} isn't a prime");
                    }
                    
            

            【讨论】:

            • 这与最受好评的答案完全相同的主要解决方案,除了它还检查所有不必要的偶数。不仅没有必要发布最受好评的答案的另一个版本,而且绝对不需要发布它的错误实现。
            • 不,这是任何人都可以作为初学者理解的最简单的答案,我在这里使用了几个数字来检查,因为我想找出为什么这个数字不是素数,哪个是它的可整除数。我想你明白我的观点
            【解决方案19】:

            我试图在使用 Any() 时从提前退出中获得一些效率...

                public static bool IsPrime(long n)
                {
                    if (n == 1) return false;
                    if (n == 3) return true;
            
                    //Even numbers are not primes
                    if (n % 2 == 0) return false;
            
                    return !Enumerable.Range(2, Convert.ToInt32(Math.Ceiling(Math.Sqrt(n))))
                        .Any(x => n % x == 0);
                }
            

            【讨论】:

            • 我喜欢这个解决方案,但它并不排除 2 作为质数
            【解决方案20】:

            这是找到素数的最简单方法是

            for(i=2; i<num; i++)
                    {
                        if(num%i == 0)
                        {
                            count++;
                            break;
                        }
                    }
                    if(count == 0)
                    {
                        Console.WriteLine("This is a Prime Number");
                    }
                    else
                    {
                        Console.WriteLine("This is not a Prime Number");
                    }
            

            有用的链接: https://codescracker.com/java/program/java-program-check-prime.htm

            【讨论】:

              【解决方案21】:

              这是一个没有其他答案“杂乱无章”的版本,而且很简单。

              static void Main(string[] args)
              {
              
                  Console.WriteLine("Enter your number: ");
                  int num = Convert.ToInt32(Console.ReadLine());
                  bool isPrime = true;
                  for (int i = 2; i < num/2; i++)
                  {
                      if (num % i == 0)
                      {
                          isPrime = false;
                          break;
                      }
                  }
                  if (isPrime)
                      Console.WriteLine("It is Prime");
                  else
                      Console.WriteLine("It is not Prime");
                  Console.ReadLine();
              }
              

              【讨论】:

                【解决方案22】:
                /***
                 * Check a number is prime or not
                 * @param n the number
                 * @return {@code true} if {@code n} is prime
                 */
                public static boolean isPrime(int n) {
                    if (n == 2) {
                        return true;
                    }
                    if (n < 2 || n % 2 == 0) {
                        return false;
                    }
                    for (int i = 3; i <= Math.sqrt(n); i += 2) {
                        if (n % i == 0) {
                            return false;
                        }
                    }
                    return true;
                }
                

                【讨论】:

                  【解决方案23】:

                  我认为这是最简单的方法。

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

                  【讨论】:

                    【解决方案24】:

                    使用传统方法找到素数的最短技术

                        public string IsPrimeNumber(int Number)
                        {
                            int i = 2, j = Number / 2;
                            for (; i <= j && Number % 2 != 0; i++);
                            return (i - 1) == j ? "Prime Number" : "Not Prime Number";
                        }
                    

                    【讨论】:

                      【解决方案25】:

                      原答案

                      • 素数是奇数,除了 2
                      • 素数不是负数
                      • 1 或 0 既不是素数也不是合数

                      接近

                      1. 添加一个计数器来检查输入数字可被 i 整除的次数(余数为 0(零))
                      2. 如果计数器 = 2,则输入是素数,否则不是素数
                      3. 如果 counter > 2 "break" 以避免不必要的过程(如果您想计算输入数字的因素,请在第一个 if 语句中删除“|| counter > 2”)
                      4. 如果您想查看有多少余数为 0(或存在因子)的数字,请在 for 循环内的第二个 if 语句中添加这行代码:
                      Console.WriteLine( $" {inputNumber} / {i} = { inputNumber / i} (remainder: {inputNumber % i})" ); 
                      
                      1. 在数字 4 中添加代码行(在 for 循环的末尾)以查看所有数字除以您的输入数字(以防您想查看余数输出和商)
                      Console.Write( "Enter a Positive Number: " );
                      int inputNumber = Convert.ToInt32( Console.ReadLine() );
                      int counter = 0;
                      
                          for ( int i = 1; i <= inputNumber; i++ ) {
                              if ( inputNumber == 0 || inputNumber == 1 || counter > 2 ) { break; }
                              if ( inputNumber % i == 0 ) { counter++; }
                          }
                      
                          if ( counter == 2 ) {
                              Console.WriteLine( $"{inputNumber} is a prime number." );
                          } else if ( inputNumber == 1 || inputNumber == 0 ) {
                              Console.WriteLine( $"{inputNumber} is neither prime nor composite." );
                          } else {
                              Console.WriteLine( $"{inputNumber} is not a prime number. (It is a composite number)" );
                          }
                      

                      我的参考:https://www.tutorialspoint.com/Chash-Program-to-check-if-a-number-is-prime-or-not



                      简化版:

                      我在这里使用uint 而不是int 来避免negative 输入。

                      public bool IsPrime(uint number)
                      {
                          if (number <= 1) { return false; }
                      
                          int counter = 0;
                          for (int i = 1; i <= number; i++)
                          {
                              if (number % i == 0) { counter++; }
                              if (counter > 2) { return false; }
                          }
                      
                          return true;
                      }
                      

                      【讨论】:

                        【解决方案26】:
                        function isPrime(n) {
                        
                            //the most speedly function
                        
                            var res = '';
                            var is_composite = false;
                            var err = false;
                            var sqrt = Math.sqrt(n);
                        
                            if (n <= 1){
                                err = true;
                            }
                        
                            if (n == 2 || n == 3){
                        
                                res = true; //"Prime"
                        
                            } else if(n % 2 == 0 || n % 3 == 0) {
                        
                                res = false; //'Composite'
                        
                            } else{
                        
                                /*here you just neet to check dividers like (6k+1) or (6k-1)
                                  other dividers we exclude in if(n % 2 == 0 || n % 3 == 0)*/
                        
                                for(let i = 5; i <= sqrt; i += 6){
                                    if (n % i == 0){
                                        is_composite = true;
                                        break;
                                    }
                                }
                        
                                if (!is_composite){
                                    for(let i=7; i <= sqrt; i += 6){
                                        if (n % i == 0){
                                            is_composite = true;
                                            break;
                                        }
                                    }
                                }
                        
                                if (is_composite){
                                    res = false; //'Composite'
                                } else {
                                    res = true; //'Prime'
                                }
                            }
                        
                            if (err) {
                                res = 'error';
                            }
                        
                            return res;
                        }
                        

                        【讨论】:

                          【解决方案27】:

                          更新

                          添加了else if (value % 2 == 0) 以消除偶数。感谢avl_sweden

                          方法

                          扩展版本:

                          public static bool IsPrime(this int value)
                          {
                              if (value < 2)
                                  return false;
                              else if (value == 2)
                                  return true;
                              else if (value % 2 == 0) /*updated*/
                                  return false;
                          
                              var root = Math.Sqrt(value);
                          
                              for (int i = 3; i <= root; i += 2)
                              {
                                  if (value % i == 0)
                                      return false;
                              }
                              return true;
                          }
                          

                          检查

                          var primes = Enumerable.Range(1, 100).Where(x => x.IsPrime());
                          Console.WriteLine(string.Join(", ", primes));
                          /* Output
                          2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
                          */
                          

                          用法

                          12.IsPrime()    //false
                          13.IsPrime()    //true
                          151.IsPrime()   //true
                          2.IsPrime()     //true
                          

                          【讨论】:

                          • 这个算法认为4是素数,这是错误的。
                          • 你说得对,我修好了。谢谢@avl_sweden
                          【解决方案28】:

                          HackerRank 挑战(运行时间和复杂性):针对多个测试用例,质数。

                          输入格式: 第一行包含一个整数 T ,即测试用例的数量。 随后的 T 行中的每一行都包含一个整数 n,用于测试素数。

                           int T = Convert.ToInt32(Console.ReadLine());
                                  int[] ar = new int[T];   
                          
                                  for (int i = 0; i < ar.Length; ++i)
                                  {
                                      ar[i] = Convert.ToInt32(Console.ReadLine());
                                  }
                          
                                  List<string> result = new List<string>();
                                  bool flag = true;
                                  for (int r = 0; r < ar.Length; ++r)
                                  {
                                      for (int i =2; i < (ar[r]>1000? ar[r]/4:ar[r]); ++i)
                                      {
                                          if (i != 1 && i != ar[r])
                                          {
                                              if (ar[r] % i == 0)
                                              {
                                                  flag = false;
                                                  break;
                                              }
                                          }
                                      }
                          
                                      if (flag && ar[r]!=1)
                                          result.Add("Prime");
                                      else
                                      {
                                          result.Add("Not prime");
                                          flag = true;
                                      }
                                        
                          
                                  }
                          
                                  foreach (var a in result)
                                  {
                                      Console.WriteLine(a);
                                  }
                          

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 2015-09-15
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2020-11-14
                            • 2020-09-20
                            相关资源
                            最近更新 更多