以下代码包含一个可能触发无限循环的错误,我无法弄清楚如何运行第二个print语句,我敢肯定修复它很简单,但是看不到它。
def smallest_prime_factor(x):
    """Returns the smallest prime number that is a divisor of x"""
    # Start checking with 2, then move up one by one
    n = 2
    while n <= x:
        if x % n == 0:
            x += 1
            return n
print(smallest_prime_factor(12)) # should be 2
print(smallest_prime_factor(15)) # should be 3
 
问题来源:stackoverflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
您陷入无限循环,因为如果不满足返回条件,则不更改n的值,因为您可以看到返回条件仅在您的数字x是2的倍数时得到满足改变 :
if x % n == 0:
    x += 1
 
与:
while n <= x:
    if x % n == 0:
        return x
    n += 1
 
为了优化代码,您可以搜索一个以质数n来除以int(math.sqrt(x)+ 1)的x:
import math
def smallest_prime_factor(x):
    """Returns the smallest prime number that is a divisor of x"""
    # Start checking with 2, then move up one by one
    n = 2
    max_n = int(math.sqrt(x) + 1)
    while n < max_n:
        if x % n == 0:
            return n
        n += 1
    return x
 
甚至更好的是,您可以使用Eratosthenes筛子快速生成质数并针对x进行测试:
# Sieve of Eratosthenes
# Code by David Eppstein, UC Irvine, 28 Feb 2002
# http://code.activestate.com/recipes/117119/
def gen_primes(y):
    """ Generate an infinite sequence of prime numbers.
    """
    # Maps composites to primes witnessing their compositeness.
    # This is memory efficient, as the sieve is not "run forward"
    # indefinitely, but only as long as required by the current
    # number being tested.
    #
    D = {}
    # The running integer that's checked for primeness
    q = 2
    while q < y:
        if q not in D:
            # q is a new prime.
            # Yield it and mark its first multiple that isn't
            # already marked in previous iterations
            # 
            yield q
            D[q * q] = [q]
        else:
            # q is composite. D[q] is the list of primes that
            # divide it. Since we've reached q, we no longer
            # need it in the map, but we'll mark the next 
            # multiples of its witnesses to prepare for larger
            # numbers
            # 
            for p in D[q]:
                D.setdefault(p + q, []).append(p)
            del D[q]
def smallest_prime_factor(x):
    """Returns the smallest prime number that is a divisor of x"""
    # Start checking with 2, then move up one by one
    return next((i for i in gen_primes(int(math.sqrt(x) + 1)) if x % i == 0), x)
 
回答来源:stackoverflow