检查C#中的数字是否为素数

时间:2016-05-20 14:43:44

标签: c#

以下代码有效,但对于某些数字,需要花费大量时间来说明数字是否为素数。我该怎么做才能让它更快?这是代码:

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

namespace Exercise23
{
    class Exercise23
    {
        static void Main(string[] args)
        {
            long number = long.Parse(Console.ReadLine());
            if (IsPrime(number))
            {
                Console.WriteLine("True");
            }
            else
            {
                Console.WriteLine("False");
            }
        }
        public static bool IsPrime(long number)
        {
            if (number == 1) return false;
            if (number == 2) return true;
            //if (number == 6737626471) return true;

            if (number % 2 == 0) return false;    

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

2 个答案:

答案 0 :(得分:3)

最简单的改进是缩短循环次数。 如果number不是prime,则可以写为

  N = A * B 

A <= B;在最坏的情况下(A == B),所以A <= sqrt(N)

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

    long N = (long) (Math.Sqrt(number) + 0.5);

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

    return true;
  }

所以你有O(sqrt(N))算法而不是O(N)。要获得真正的改进(对于 number s),请参阅

AKS 测试(主要是学术用途)

https://en.wikipedia.org/wiki/AKS_primality_test

Rabin-Miller 测试

https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test

答案 1 :(得分:1)

根据这个答案:https://stackoverflow.com/a/26760082/4499267 加快速度的方法可以是:

  • 通过观察所有素数的形式为6k±1,可以进一步改进算法,但2和3除外。
  • 这是因为对于某些整数k和i = -1,0,1,2,3或4,所有整数可以表示为(6k + i); 2除(6k + 0),(6k + 2),(6k + 4);和3分(6k + 3)。
  • 因此,更有效的方法是测试n是否可被2或3整除,然后检查所有形式的数字6k±1≤√n。
  • 这是测试所有m到√n的速度的3倍。

这是一个C实现

int IsPrime(unsigned int number) {
    if (number <= 3 && number > 1) 
        return 1;            // as 2 and 3 are prime
    else if (number == 1 || number%2==0 || number%3==0) 
        return 0;     // check if number is divisible by 2 or 3
    else {
        unsigned int i;
        for (i=5; i*i<=number; i+=6) {
            if (number % i == 0 || number%(i + 2) == 0) 
                return 0;
        }
        return 1; 
    }
}