【问题标题】:Euler Project #3 in PythonPython 中的 Euler 项目 #3
【发布时间】:2012-11-10 07:09:00
【问题描述】:

我正在尝试用 Python 解决 Project Euler 问题 3:

The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143 ?

我知道我的程序效率低下且体积过大,但我只是想知道为什么它不起作用? 代码如下:

def check(z):

# checks if the given integer is prime

    for i in range(2, z):
        if z % i == 0:
            return False
            break
        i = i+1
    return True

def primegen(y):
# generates a list of prime integers in the given range

    tab = []
    while y >= 2:
        if check(y) == True:
            tab.append(y)
        i = i-1


def mainfuntion(x):
# main function; prints the largest prime factor of the given integer

    primegen(x)
    for i in range(len(tab)):
        if x % tab[i] == 0:
            print tab[i]
            break

mainfuntion(600851475143)

这是错误:

for i in range(2, z):
OverflowError: range() result has too many items

【问题讨论】:

  • 你在primegen 中混合了iy。至于报错,试试xrange
  • 像你正在做的那样在mainfunction 中引用变量tab 是不好的做法。您对primegen() 的调用可能会返回质数列表,您可以将其分配给一个变量:primes = primegen(x),然后是下一行for i in xrange(len(primes))
  • 欢迎来到 Stackoverflow。我为你格式化了你的代码,但是请看thisthis,下次正确格式化代码块。
  • 另一方面,这是一种非常低效的方法。 O(n² / log n)。

标签: python


【解决方案1】:

原因是 Python 中的列表限制为 536,870,912 个元素(请参阅How Big can a Python Array Get?),当您在示例中创建范围时,元素的数量超过了该数量,从而导致错误。

Project Euler 的乐趣在于您自己解决问题(我知道您正在这样做:)),所以我将给出一个非常小的提示来绕过该错误。想想一个数的因数是什么——你知道 600851475142 不可能是 600851475143 的因数。因此你不必一直检查到那个数。按照这个逻辑,有没有办法可以显着减少检查的范围?如果你对素因数的性质做一些研究,你可能会发现一些有趣的东西:)

【讨论】:

  • 您可以将 range 替换为 xrange,它不会将整个元素列表存储在内存中。
  • @barracel 确实 :) 我将在一分钟内添加更新(在会议中:))
  • 虽然 xrange 在 2.x 系列中是“优化的”,因此实现只需要接受符合标准 C 的东西 long - @RocketDonkey 在上述会议中不是很忙吗? :)
  • 即使使用xrange,在 11891268401 处将达到 536870912 个素数,此方法适用的最大数是 11891268406,估计运行时间为 20,000 年,给定或取因子 3。
  • @JonClements Ha,会议 - 提高工作效率的最佳方式,同时提高效率!
【解决方案2】:

首先,在第一个代码块中,不要使用i = i+1,因为 for 循环会处理它。其次,使用xrange 来制作生成器而不是列表。

【讨论】:

    【解决方案3】:

    这是我使用的代码!!

    n = 600851475143
    i = 2
    while i * i < n:
         while n % i == 0:
             n = n / i
         i = i + 1
    
    print n
    

    -M1K3

    【讨论】:

      【解决方案4】:

      @seamonkey8: 你的代码可以改进。您可以将其增加 2 而不是 1。对于非常大的数字,它会产生速度差异:

      n,i = 6008514751231312143,2
      
      while i*i <= n:      
          if n%i == 0:
              n //= i
          else: 
              i+=[1,2][i>2]
      

      【讨论】:

        猜你喜欢
        • 2020-10-30
        • 1970-01-01
        • 2019-10-24
        • 1970-01-01
        • 1970-01-01
        • 2012-10-11
        • 2023-03-21
        相关资源
        最近更新 更多