IsPrime功能错误?

时间:2012-09-19 20:22:49

标签: python

我写了这个函数来检查一个数字是否为素数。它本身似乎工作正常但是当我在另一个函数中使用它时,它似乎不起作用。

这是我的IsPrime功能:

def is_prime(n):
    boolean = False
    if n == 2 or n == 3:
            return True
    for x in range(3, int(n**0.5)+1, 2):
        if n % x == 0:
            return False
    return True

下面的函数计算2000000下所有素数的总和:

def problem10(prime, result):
    if prime > 2000000:
        return 
    if is_prime(prime):
        print 'prime is ', prime 
        result = result + prime
        problem10(prime + 1, result)
    return result

我无法理解我哪里出错了。

评论将不胜感激。

6 个答案:

答案 0 :(得分:6)

is_prime没有检查偶数。例如,如果你传递它4,它会看到它既不是2也不是3,然后进入循环,它将执行一次,检查它是否可被3整除(它不是)。退出循环时,当我们知道4实际上不是素数时,它将返回True

答案 1 :(得分:3)

您的problem10功能流程中存在错误。归结为您实际上并未使用递归problem10函数的结果值。你希望你的代码看起来像这样(假设你想保持递归,你可能想要考虑一个循环):

def problem10(prime):
    """ calculates the sum of primes from this prime until 2000000 (2 * 10**6) """
    if prime >= 2000000:
       return 0
    elif is_prime(prime):
       return prime + problem10(prime + 1)
    else:
       return problem10(prime + 1)

请注意,此功能方法有几个要考虑的关键点:

  1. 如果prime> = 2000000,则此函数表示空的总和。因此返回0。
  2. 如果是is_prime(素数),则此函数应将素数添加到总和
  3. 否则总和与下一个数字的素数之和相同(因为我们必须排除较低的数字,因为它不是素数)。
  4. 与原始尝试相比:请注意如何在return语句中使用表达式可以大大简化函数的逻辑(流程)。它真的更具可读性。另外,请注意您的原始功能永远不会起作用,因为:

    一个。您的函数不会更新运行总计(结果)

    湾即使它确实如此,最终你最终会将None添加到某个东西,因为你的原始函数在prime> = 2000000的情况下没有返回任何内容。

答案 2 :(得分:1)

更快的素数列表是这样的:

import numpy as np

def primesfrom2to(n):
    """ Returns a array of primes, p < n """
    assert n>=2
    sieve = np.ones(n/2, dtype=np.bool)
    for i in xrange(3,int(n**0.5)+1,2):
        if sieve[i/2]:
            sieve[i*i/2::i] = False
    return np.r_[2, 2*np.nonzero(sieve)[0][1::]+1]    

然后只是总和:

print sum(primesfrom2to(2000000))    

如果你想使用你的功能,这里有一个建议的重写:

def is_prime(n):
    if n in (2,3):
        return True
    if not n%2:
        return False        
    if any(n%x == 0 for x in xrange(3, int(n**0.5)+1, 2)):     
        return False   
    return True 

答案 3 :(得分:1)

这是你的is_prime函数的正确版本,它使用2的试验除法和从3到 n 的平方根的奇数来确定n是素数还是复合数:

def is_prime(n):
    if n % 2 == 0:
        return n == 2
    d = 3
    while d * d <= n:
        if n % d == 0:
            return False
        d += 2
    return True

解决问题的更好方法是使用Eratosthenes筛选识别所有小于2000000的素数,然后求它们。这是一个简单的Eratosthenes筛子:

def sieve(n):
    b, p, ps = [True] * (n+1), 2, []
    for p in xrange(2, n+1);
        if b[p]:
            ps.append(p)
            for i in xrange(p+p, n+1, p):
                b[i] = False
    return ps

有更好(更快)的方法来确定数字是素数还是复数,并生成所有素数的列表,但这些方法足以满足您的任务。

答案 4 :(得分:0)

您是否应该检查范围

for x in range(2, sqrt(n)+1):
    if n % x == 0:
        return False

根不会比平方根大。

答案 5 :(得分:0)

def isPrime(num,div=2):
if(num==div):
    return True
elif(num % div == 0):
    return False
else:
    return isPrime(num,div+1)