Python“OverflowError”

时间:2012-05-28 02:30:25

标签: python overflow

我刚开始学习用Python编写代码。我正在尝试编写一些代码来回答这个Project Euler问题:

13195的主要因素是5,7,13和29。

600851475143的最大主要因素是什么?

我的程序适用于13195的测试用例,但是当我尝试输入600851475143时,我收到错误:“OverflowError:range()结果有太多项目” 有谁知道我怎么解决这个问题?

这是我的代码:

class Euler3:
    "A class to find the largest prime factor of a given number"
     n = 600851475143
     primeFactors = []
     for i in range(2,n):
         if (n%i ==0):
            primeFactors.append(i)
            n = n/i
            i = i -1 #reset i
     print primeFactors

非常感谢任何帮助或建议!

8 个答案:

答案 0 :(得分:18)

range函数创建一个列表并尝试将其存储在内存中。创建一个很长的列表是造成OverflowError的原因。您可以使用xrange来获取按需生成数字的生成器。

那就是说,我认为你会发现你的算法对于计算大质数而言太慢了。有很多素数算法,但我可能会建议以Sieve of Eratosthenes作为起点。

编辑:正确地xrange实际上不返回生成器,而是一个xrange对象,其行为很像生成器。我不确定你是否在意,但这让我觉得我不准确!

答案 1 :(得分:4)

我猜你正在使用python 2而不是python 3 - range(2,n)实际构建了一个列表!你没有足够的内存来存储6000亿个数字! xrange应该没问题。

此外,您对i=i-1的想法不起作用。 For循环不像C一样工作,而且hack只能在C风格的循环中工作。 for循环遍历range(2,n)。如果i一次性获得值5,那么无论您对i做了什么,下一次仍然会6

此外,当您进入循环时,将构建列表range(2,n)。因此,当您修改n时,这不会改变任何内容。

你将不得不重新考虑一下你的逻辑。

(如果您不相信我,请尝试使用175作为测试用例)

作为最后一条评论,你应该养成使用特殊整数除法的习惯:n = n // i。虽然///在python 2中的工作方式相同,但这是非常弃用的行为,并且在python 3中它们不起作用,其中/将为您提供浮点数

答案 2 :(得分:4)

您可以使用xrange代替range

来解决问题

你的下一个问题是程序运行时间太长,因为你需要在某种情况下突破循环

处理重复因素的更好方法是将if替换为while

     while (n%i ==0):
        primeFactors.append(i)
        n = n/i

答案 3 :(得分:2)

n = 600851475143
primeFactors = []
for i in range(2,n):

我认为您可以通过注意

来优化功能
for i in range(2,n):

你可以替换

range(2,n)

通过

range(2,int(sqrt(n))+2)

因为,你可以看到维基...

答案 4 :(得分:1)

这是找到我到目前为止找到的素数的最佳方法:

def isprime(n):
    #make sure n is a positive integer
    n = abs(int(n))
    #0 and 1 are not primes
    if n < 2:
        return False
    #2 is the only even prime number
    if n == 2:
        return True
    #all other even numbers are not primes
    if not n & 1:
        return False
    #range starts with 3 and only needs to go up to the square root of n
    #for all odd numbers
    for x in range (3, int(n**0.5)+1, 2):
        if n % x == 0:
            return False
    return True #if it makes it through all the catches, it is a prime

答案 5 :(得分:1)

我花了大约5秒来得到答案。

import math

def is_prime_number(x):
   for i in range(int(math.sqrt(x)), 2, -1):
      if x % i == 0:
        return False
   return True

def next_prime_number(number):
    #Returns the next prime number.
    if number % 2 == 0 and number != 2:
        number += 1
    while not is_prime_number(number):
        number += 2
    return number

num = 600851475143
i = 2
while (i < long(math.sqrt(num) / 2)):
    if num % i == 0:
       largest = i
       print largest
    i = next_prime_number(i + 1)

答案 6 :(得分:1)

xrange不可能帮助你(或者它可能!),但关键是要解决你不需要找到素数直到600851475143或因子600851475143,但它的主要因素,所以...... 使用好的旧素数分解方法,如下:

A=600851475143
n=2
fac=[]
while(n<=int(A)):
    B=1
    while(A%n==0):
        B=0   
        A=A/n
    if(B==0):
        fac.append(n)
    n=n+1

print max(fac)

这将立即返回最大的素数因子

答案 7 :(得分:0)

我正在与这个Python“OverflowError”作斗争,正在处理这个项目。这让我疯狂,试图想出一个有效的组合。

然而,我确实发现了一个聪明的人,至少我是这么认为:),这样做的方法。

以下是此问题的代码。

def IsNumberPrime(n):
   bounds = int(math.sqrt(n))
   for number in xrange(2,bounds+2):
        if n % number == 0:
            return False
   return True

def GetListOfPrimeFactors(n):
    primes = []
    factors = GetListOfFactors(n)
    if n % 2 == 0:
       primes.append(2)

    for entries in factors:
       if IsNumberPrime(entries):
          primes.append(entries)
    return primes


GetListOfPrimeFactors(600851475143)

def GetListOfFactors(n):
   factors = []
   bounds = int(math.sqrt(n))
   startNo = 2

   while startNo <= bounds:
      if n % startNo == 0:
         factors.append(startNo)
      startNo += 1
   return factors

我所做的是将输入数字的因子输入到“因子”列表中。之后,我拿出因素列表并确定哪些是素数并将它们存储到列表中,然后打印出来。

我希望这会有所帮助

- 迈克