检查数字是不是为素数

Posted

技术标签:

【中文标题】检查数字是不是为素数【英文标题】: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 是否是筛子中的素数,那么您的算法会逐渐变差(并且常数因子也不会让它在小数中获胜)。 【参考方案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 ≠

    那么因素之一 ab 最多必然是 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 写得不好)。还有:***.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);
        
    

【讨论】:

最好还添加一个简短的解释代码的作用以及它背后的核心思想是什么——这将使答案对初学者更容易阅读更有用。欢迎来到 ***!【参考方案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;
        

【讨论】:

任何大的数字都会导致 ***Excpetion。 正确。因为递归的深层次。这就是我第一次发布迭代方法的方式。递归是优雅的;)【参考方案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 既不是素数也不是合数

接近

    添加一个计数器来检查输入数字可被 i 整除的次数(余数为 0(零)) 如果计数器 = 2,则输入是素数,否则不是素数 如果 counter > 2 "break" 以避免不必要的过程(如果您想计算输入数字的因素,请在第一个 if 语句中删除“|| counter > 2”) 如果您想查看有多少余数为 0(或存在因子)的数字,请在 for 循环内的第二个 if 语句中添加这行代码:
Console.WriteLine( $" inputNumber / i =  inputNumber / i (remainder: inputNumber % i)" ); 
    在数字 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);
        

【讨论】:

以上是关于检查数字是不是为素数的主要内容,如果未能解决你的问题,请参考以下文章

在Python中检查一个数字是不是是素数[重复]

python 检查数字是否为素数

为啥我们要检查素数的平方根以确定它是不是为素数?

筛素数

查找 i*i+1 是不是为素数,汇编语言

具有素数列表的高效素数分解算法