【问题标题】:Takes forever :Project Euler Problem 3 Python永远需要:Project Euler Problem 3 Python
【发布时间】:2020-04-09 18:55:58
【问题描述】:

我是初学者。我的Project Euler Problem No. 3 解决方案需要永远返回答案。有人可以建议改进吗?我究竟做错了什么?我已经编写了一些代码来帮助我思考问题的所有谜题。

13195 的质因数是 5、7、13 和 29。

600851475143 的最大质因数是多少?

#limiter identification for iteration

def limiter(x):
    for i in range (2, x):
        if x % i == 0:
            return int (x/i)

#Prime checker 
            
def is_prime(a):
    for i in range (2, a):
        if a % i == 0:
            return False
    return True
#Lists all factors of a given no.

def factorlist(b):
    list = []
    for i in range (2, limiter(b)+1):
        if b % i == 0:
            list.append(i)
    return list

#Lists all prime factors of a given no.

def primefactor(p):
    plist = []
    for i in factorlist(p):
        if is_prime(i)== True:
            plist.append(i)
            
    return plist
    
print (primefactor(600851475143)[-1])

【问题讨论】:

  • 对于此类问题,查看您知道答案的较小案例总是有帮助的。这个程序是否真的为小数字返回正确的结果?
  • 是的,确实如此。如果我只是取出输入的最后一位,它会很快给出正确的结果。添加最后一位数字似乎会导致延迟。
  • 1) limiter 背后的想法是什么? 2) 当您检查它是否是素数时,您只需要迭代直到sqrt(a)(如果一个除数大于sqrt(a),另一个小于)。不确定这是否是唯一的问题,但肯定会更快。
  • 一旦你有一些基本可以工作的东西并且你想让它更快,试着写下它为一个小案例所遵循的步骤。有没有重复的?如果是这样,有没有办法可以避免做一些重复?对于典型的早期欧拉问题(实际上是计算机科学中的大多数问题),每一步都应该让你得到一个答案,并为你留下相同问题的较小版本,直到最后一步给你最后一个答案。跨度>
  • 我没有想到 sqrt(a)。谢谢它应该大大减少计算。再告诉我一件事;我将输入的所有因素附加到一个列表中,然后使用迭代检查是否为素数。如果素数则附加到另一个列表并最终返回最后一项。这种方法内存效率高吗?有没有其他更好的方法。我相信递归会带来类似的内存问题。

标签: python prime-factoring


【解决方案1】:

我没有答案,但我会说有时函数中的 print() 语句将被证明对函数中的调试很有用。您的 limiter() 函数在 71 处挂起的示例。我发现在我的机器上运行您的程序:

def limiter(x):
for i in range (2, x):
    print(i) <------------------ I added this
    if x % i == 0:
        return int (x/i)

因此,在您的函数中添加 print() 可能会有所帮助。

【讨论】:

    【解决方案2】:

    寻找最大素因数的递归方法会更简单,而且可能更快:

    def lpf(N,p=2):                               # start from preceding prime factor
        for f in range(p,int(N**0.5)+1):          # factors up to square root
            if N%f==0 : return max(f,lpf(N//f,f)) # 1st prime vs lpf of counterpart
        return N # none found, N is prime itself
    
    lpf(600851475143) # 6857
    

    【讨论】:

      【解决方案3】:

      这里有更简单和更短的代码:

      # Largest Prime Factor
      
      def prime_number(b):
          c1 = 0
          for i in range(1,int(b/2)+1):
              if b % i == 0:
                  c1 += 1
          if c1 < 2:
              return(True)
          else:
              return(False)
      
      def prime_factor(a):
          n = 0
          count = 1
          prime = 0
          while n < a+1:
              n += 1
              if a % n == 0:
                  if prime_number(n) == True:
                      prime = n
                      print(prime)
      prime_factor(600851475143)
      

      【讨论】:

      • for i in range(1,int(b/2)) 应该是 for i in range(1,int(b/2)+1)
      猜你喜欢
      • 2021-07-14
      • 2012-10-11
      • 1970-01-01
      • 1970-01-01
      • 2015-05-17
      • 2010-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多