寻找最大的除数(可能是最快的程序)

时间:2013-12-14 09:11:15

标签: python python-3.x

我正在检查http://projecteuler.net/

上的问题

第三个问题如下:

  

13195的主要因素是5,7,13和29.最大的是什么   数字的主要因素600851475143?

我的解决方案代码如下。但它太慢了,我认为需要数周才能完成。 我怎样才能改进它?或者Python本身太慢,无法解决这个问题?

def IsPrime(num):
    if num < 2:
        return False
    if num == 2:
        return True
    else:
        for div in range(2,num):
            if num % div == 0:
                return False
        return True

GetInput = int (input ("Enter the number: "))


PrimeDivisors = []

for i in range(GetInput, 1, -1):
    print(i)
    if GetInput % i == 0 and IsPrime(i) is True:
        PrimeDivisors.append(i)
        break
    else:
        continue


print(PrimeDivisors)
print("The greatest prime divisor is:", max(PrimeDivisors))

4 个答案:

答案 0 :(得分:2)

你的解决方案的问题在于你没有考虑到你发现的素因子,所以在你真正找到最大因素之后你就会不必要地检查因素。这是我的解决方案:

def largest_prime_factor(n):
    largest = None

    for i in range(2, n):
        while n % i == 0:
            largest = i
            n //= i

        if n == 1:
            return largest

    if n > 1:
        return n

项目欧拉问题更多的是关于数学而不是编程,所以如果你的解决方案太慢,那可能不是你的语言有问题。

请注意,我的解决方案很快就会针对此特定数字运行,因此它绝对不是一般解决方案。更快的解决方案are complicated并且在这种特定情况下过度杀伤。

答案 1 :(得分:1)

这可能不是最快的算法,但它非常有效:

def prime(x):
    if x in [0, 1]:
        return False
    for n in xrange(2, int(x ** 0.5 + 1)):
        if x % n == 0:
            return False
    return True

def primes():
    """Prime Number Generator

    Generator an infinite sequence of primes

    http://stackoverflow.com/questions/567222/simple-prime-generator-in-python
    """

    # 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 True:
        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]

        q += 1

def primefactors(x):
    if x in [0, 1]:
        yield x
    elif prime(x):
        yield x
    else:
        for n in primes():
            if x % n == 0:
                yield n
                break
        for factor in primefactors(x // n):
            yield factor

<强>用法:

>>> list(primefactors(100))
[2, 2, 5, 5]

答案 2 :(得分:1)

我的代码对我来说似乎足够快。使用collections.defaultdict()可以使primes()的代码更加清晰,但我想代码会因为导入代码而失去一些速度。

def primes():
    """Prime number generator."""
    n, skip = 2, {}
    while True:
        primes = skip.get(n)
        if primes:
            for p in primes:
                skip.setdefault(n + p, set()).add(p)
            del skip[n]
        else:
            yield n
            skip[n * n] = {n}
        n += 1

def un_factor(n):
    """Does an unique prime factorization on n.

    Returns an ordered tuple of (prime, prime_powers)."""
    if n == 1:
        return ()
    result = []
    for p in primes():
        (div, mod), power = divmod(n, p), 1
        while mod == 0:
            if div == 1:
                result.append((p, power))
                return tuple(result)
            n = div
            div, mod = divmod(n, p)
            if mod != 0:
                result.append((p, power))
            power += 1

试运行:

>>> un_factor(13195)
((5, 1), (7, 1), (13, 1), (29, 1))
>>> un_factor(600851475143)
((71, 1), (839, 1), (1471, 1), (6857, 1))
>>> un_factor(20)
((2, 2), (5, 1))

编辑:基于this食谱的primes()生成器的微小编辑。

EDIT2:固定为20。

EDIT3:用un_factor()替换了great_prime_divisor()。

答案 3 :(得分:0)

def getLargestFactor(n):
    maxFactor = sqrt(n)
    lastFactor = n
    while n%2 == 0:
        n  /= 2
        lastFactor = 2
    for i in xrange(3,int(maxFactor),2 ):
        if sqrt(n) < i:
             return n
        while n%i == 0 and n > 1:
            n  /= i
            lastFactor = i
    return lastFactor

这应该相当有效。将每个因素全部分开,这样我们只找到素因子。并且使用的事实是,只有一个大于sqrt(n)的数的素因子。