素数发生器花费太多时间

时间:2013-03-14 05:02:09

标签: python prime-factoring

我正在解决这个问题:

  

通过列出前六个素数:2,3,5,7,11和13,我们可以看到第6个素数是13。   什么是10 001主数?

def checkPrime(x):
    facs = 0
    for i in range(1,x):
        if x%i==0:
            facs = facs + 1
    if facs == 2:
        return True
    else :
        return False

i = 1
noPrime = 0
done = False
while(done==False):
    i = i + 1
    print "i = {0} and noPrime={1}".format(i,noPrime)
    if checkPrime(i)==True:
        noPrime = noPrime + 1
        if noPrime==10001 :
            print i
            done=True

但这需要花费很多时间 我怎样才能加快速度?

4 个答案:

答案 0 :(得分:5)

使用素性测试的方法:

def isPrime(n):
    if n == 2: return True
    if n % 2 == 0 or n < 2: return False
    for i in range(3, int(n**0.5)+1, 2):
        if n % i == 0: return False
    return True
if __name__ == "__main__":
    n = count = 1
    while count < 10001:
        n += 2
        if isPrime(n): count += 1
    print n

在0.2秒内运行。这个问题无关紧要,但正如其他人所说,筛子更有效率。

答案 1 :(得分:4)

您可以使用prime number theorem来估算您需要走多远的距离。 (估计程序中数组p的大小)。 pi(n),小于n的素数的数量渐近n%^.nn除以ln n)。对于第10001个素数,等式为10001=n%^.n,求解n得到n在1.1e5和1.2e5之间。

因此,您可以缩小选中值的范围并仅检查范围的数字。这种技术减少了程序的运行时间。

答案 2 :(得分:2)

您不需要使用Sieve of Eratosthenes (虽然您将来会遇到问题)。找到10001素数相对较快。

注意事项:

  • 仅测试奇数(#2除外)
  • 您只需要测试除数值的平方根之外的除数。

下面的剧透 - 假设你已经解决了问题,但这只需要很长时间

C#中的示例(抱歉,不知道python):

class Program
{
    static bool IsPrime(int value)
    {
        if (value == 2) return true;
        if (value % 2 == 0) return false;

        // Test for divisors up to the square root of "value", increment by 2.
        for (int i = 3; i <= Math.Sqrt(value); i += 2)
        {
            if (value % i == 0)
                return false;
        }
        return true;
    }

    static void Main(string[] args)
    {
        int primeCount = 1; // #2

        // Test only odd numbers.
        for (int i = 3; ; i += 2)
        {
            if (IsPrime(i))
            {
                primeCount++;
                if (primeCount == 10001)
                {
                    Console.WriteLine(i.ToString());
                    break;
                }
            }
        }
        Console.ReadLine();
    }
}

答案 3 :(得分:2)

由于其他人都在发布他们的解决方案,我认为我会对简单划分方法做一些明显的改进:

def is_prime(nr):
    if nr < 2: return false
    if nr < 4: return true
    if nr % 2 == 0: return false
    if nr < 9: return true
    if nr % 3 == 0: return false
    for i in range(5, int(nr**0.5) + 1, 6):
        if number % i == 0: return false
        if number % (i + 2) == 0: return false
    return true

通过摆脱一个不必要的模运算,这改进了简单的解决方案。