python是否显示大整数的问题?

时间:2011-01-18 04:10:27

标签: python

我有一个代码来计算600851475143的最高素数因子。

def PRIME(a):                #Check if no is prime
    f = 0
    i = 2
    while(i < a/2):          #No factor of a no can be greater than a/2
        if (a % i == 0):
            f = 1
            break
        i = i + 1

    if(f == 1):
        return 0
    else:
        return 1


def PFIND(a):
    for i in range(1, 100000):   #Iteratively check if the no is prime
        if PRIME(a/2 - i):       #No factor of a no can be greater than a/2.
            if (a % (a/2 - i) == 0):
                return (a/2 - i)
print PFIND(600851475143)

但是代码会继续运行,并且不会给出任何输出。

6 个答案:

答案 0 :(得分:8)

Python对大整数的支持很好。我认为你的问题是,你正在为蛮力发现因素和测试你的因素是否为素数做非常慢的算法。如果你只是颠倒这两个测试的顺序(即,测试它是否是一个因素,然后测试它是否是素数),它会更快。

但也许问题在于使用更复杂的算法。也许你应该使用Rabin-Miller test而不是暴力。

答案 1 :(得分:3)

不是从大量的测试开始,而是在较小的数字上尝试算法。然后逐渐尝试更大的数字。绘制函数所花费的时间 - 我建议使用timeit模块。然后推断并估计函数对你正在尝试的数字的持续时间。

我认为你会发现你的算法花了很长时间才看起来它永远不会完成。

答案 2 :(得分:0)

您的循环条件

while(i < a/2):

使您的算法花费O(N)时间。

简单的修改会将其改进为O(√N)。

hi = int(math.sqrt(a) + 1)     # +1 in case of rounding error.
while i <= hi:

答案 3 :(得分:0)

我发现Python在大整数方面做得很好。如前所述,你正在使用两个强力测试来破解这个坚果。

试试这个:

a = 600851475143
q = 2

while q <= a / 2:
    if not a % q:
        a /= q
        p = q
    else:
        q += 1

print p

答案 4 :(得分:0)

我写了一些与过去的素数有关的爱好代码,我已经适应了你的目的。这是代码:

def isPrime(n, primes=[]):
    """ Return True iff n is a prime number.
            If primes is non-empty, return true iff n is co-prime to every number in primes. """

    if not len(primes):
            if n <= 2:
                    return True
            elif n%2 == 0:
                    return False
            else:
                    prime = True
                    for i in range(3, n, 2):
                            if n%i == 0:
                                    prime = False
                    if prime:
                            return True
    else:
            for p in primes:
                    if not n%p:
                            return False
            return True

def next(n, primes):
    """ Return a number p such that
            1. p is co-prime to every number in primes
            2. p>n and p-n is as small as possible"""

    curr = n+1
    while 1:
            if isPrime(curr, primes):
                    return curr
            else:
                    curr += 1

def generate(n):
    """ Yield the first n prime numbers"""

    primes = [2]
    curr = 2
    for _ in range(n-1):
            p = next(curr, primes)
            primes.append(p)
            curr = p
            yield p

def primeNumbers(n):
    """ return a list of prime numbers such that all numbers in the list are at most n
            1 is a prime number"""

    answer = []
    if n <= 2:
            answer.append(n)
    else:
            for i in range(3, n+1, 2):
                    prime = True
                    for p in answer:
                            if i%p == 0:
                                    prime = False
                                    break
                    if prime:
                            answer.append(i)

    return answer

def PFIND(n):
    primes = primeNumbers(n)
    primes.reverse()
    for p in primes:
        if n%p == 0:
            return p

应该这样做。

希望这有帮助

答案 5 :(得分:0)

Python的长期支持是非常冗长和经过充分测试的,所以我怀疑这是问题所在。我注意到你的代码的一件事是它根本没有被优化,并且在循环的每次迭代期间多次计算值a/2。然而,即使您修复了它可能仍然太慢,因为finding prime factors可能非常耗时,特别是对于较大的数字。

出于这个原因,我认为最好的方法是找到更好的算法。这里的代码派生自我发现的代码,它计算了数字的所有素因子。我将它转换为Python并将其简化为跟踪它找到的最大因素。它迅速为您的测试用例返回了正确的答案,其主要因素为{71,839,1471,&amp; 6857}。

def maxprimefactor(n):
    """ find the largest prime factor of a positive integer """
    maxfactor = None
    divisor = 2
    while divisor*divisor <= n:
        if n % divisor:
            divisor += 1
        else:
            maxfactor = divisor
            n /= divisor
    if n != 1:
        maxfactor = n

    return maxfactor if maxfactor else 1

print maxprimefactor(600851475143)
# 6857