Python:尝试使用try-except-else语句进行递归素性测试

时间:2016-02-12 01:32:02

标签: python recursion primes

我一直在学习递归和错误处理。我很难理解为什么我的素性测试不起作用:

def is_prime4(n):
    """Recursive primality test"""
    try:
        div
    except NameError:
        div = n - 1
    else:
        div = div - 1
    while div >= 2:
        if n % div == 0:
            print 'No, {number} is not prime because it is divisible by {div}.'.format(number = n, div = div)
            return False
        else:
            return is_prime4(n)
    else:
        print 'Yes, {number} is prime indeed.'.format(number = n)
        return 'True'

is_prime4(2)
is_prime4(3)
is_prime4(4)

我认为问题出现在try-except-else语句中,但我很难理解为什么。

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

递归深度问题是因为 div 是每个本地上下文的新内容。 不是全局变量。每次进入例程时,都会获得一个新的上下文,包括一组新的局部变量。因此,如果您有 n = 7 ,则每个调用设置 div = 6 。你永远不会改变它,所以你进入无限递归。

您需要采用更清洁的解决方案,例如其他海报建议的解决方案。

以下是您的代码,使用全局 div 。请注意,你必须在每次完成后重置它...不知怎的......它很难看......

div = -1

def is_prime4(n):
    """Recursive primality test"""
    global div
    if div < 0:
        div = n - 1
    else:
        div = div - 1

    while div >= 2:
        if n % div == 0:
            print 'No, {number} is not prime because it is divisible by {div}.'.format(number = n, div = div)
            div = -1
            return False
        else:
            return is_prime4(n)
    else:
        print 'Yes, {number} is prime indeed.'.format(number = n)
        div = -1
        return True

    for i in range(20):
        is_prime4(i)

输出:

Yes, 0 is prime indeed.
Yes, 1 is prime indeed.
Yes, 2 is prime indeed.
Yes, 3 is prime indeed.
No, 4 is not prime because it is divisible by 2.
Yes, 5 is prime indeed.
No, 6 is not prime because it is divisible by 3.
Yes, 7 is prime indeed.
No, 8 is not prime because it is divisible by 4.
No, 9 is not prime because it is divisible by 3.
No, 10 is not prime because it is divisible by 5.
Yes, 11 is prime indeed.
No, 12 is not prime because it is divisible by 6.
Yes, 13 is prime indeed.
No, 14 is not prime because it is divisible by 7.
No, 15 is not prime because it is divisible by 5.
No, 16 is not prime because it is divisible by 8.
Yes, 17 is prime indeed.
No, 18 is not prime because it is divisible by 9.
Yes, 19 is prime indeed.

答案 1 :(得分:1)

考虑以下示例。我相信我已经简化了你的逻辑。

def recursive_prime(n,divisor=2):
    if n == divisor : return True
    elif (n % divisor) == 0: return False
    return recursive_prime(n,divisor+1)

for i in range(2,10):
    print i,'is prime',recursive_prime(i)

答案 2 :(得分:1)

您基本上尝试执行while循环并以递归方式调用该函数。它可以工作但不是这样的。我建议使用循环或递归。

您的代码还有另外两个缺点:您的递归永远不会结束,如果结束,您的循环将永远不会结束。

循环(终止)的一个例子是:

def is_prime4(n):
    """Recursive primality test"""
    div = n # very inefficient because one would only need to start at int(sqrt(n))
    while div > 2:
        div -= 1 # So that the loop terminates in the end.
        if n % div == 0:
            print('No, {number} is not prime because it is divisible by {div}.'.format(number = n, div = div))
            return False
    else:
        print('Yes, {number} is prime indeed.'.format(number = n))
        return True

is_prime4(2)
is_prime4(3)
is_prime4(4)