【问题标题】:Why doesn't my answer to project euler 3 work?为什么我对项目 euler 3 的回答不起作用?
【发布时间】:2015-11-03 17:19:55
【问题描述】:

一段时间以来,我一直在尝试解决项目欧拉问题 #3。下面的代码仍然不能按照我想要的方式工作。

问题3:13195的质因数是5、7、13、29。

600851475143 的最大质因数是多少?

 getal = 13195
    x = 2 

    while x in xrange(2,getal):
        if getal % x == 0:
            num = getal / x
            for i in xrange (2,num):
                    if num % i == 0:
                        x += 1
                        break
                    else:
                        print num
        else:
            x += 1
            continue

如您所见,为了简单起见,我现在使用 13195 运行它,但最终它应该使用更大的数字。

我的输出是这样的:

2639 2639 2639 2639 2639 1885 1885 1885 1015 1015 1015 455 455 455 377
377 377 377 377 377 377 377 377 377 377 203 203 203 203 203 145 145
145 91 91 91 91 91 65 65 65 35 35 35 29 29 29 29 29 29 29 29 29 29 29
29 29 29 29 29 29 29 29 29 29 29 29 29 29

29 持续了一段时间,比我展示的要长。 我确实理解它只是在找到不能除以该数字的“i”后立即打印该数字。但我不知道如何防止它这样做。因为最终 29 是正确的答案,但是它应该立即给出这个答案。

【问题讨论】:

  • 欧拉问题非常适合学习编码!很高兴你玩得开心。坚持下去;坚持会赢得胜利。当你学习编码时,试着用英语解释你的算法。然后将其转换为伪代码和/或 Python。当你用人类语言解释你的算法时,我想你会认为它不是正确的算法。
  • 正如其他人指出的那样,这不是最好的方法 - 您可能应该生成最大数的 sqrt 的素数,然后找到最大的有效
  • 在 SO 上多次询问和回答,例如here(别管“Java”语言标签,答案中有算法讨论和伪代码)。 --- 或者,this answer 有更详细的示例。
  • 感谢您的回答!实际上,我试图用英语提出一种算法,然后将其翻译成代码。所以现在就是:选择“getal”可以除以的所有数字(开始除以低数字,首先得到更大的“num”)然后检查这些数字是否是素数。我知道这不是最优化的代码,但是您的建议是什么?我很想得到一些建议,以便将来改进我的算法。

标签: python primes


【解决方案1】:

您可以将代码简化为下面的代码 sn-p。它使用一个列表来存储任何候选者,然后如果它们不是素数则将其删除:

import math

getal = 600851475143
x = 2 
candidates = [];
while (x < int(math.sqrt(getal)+1)):    
    if getal % x == 0:                
        candidates.append(x)
        for i in xrange (2,int(math.sqrt(x)+1)):
             if x % i == 0:
                 candidates.remove(x)
                 break        
    x = x + 1
print str(candidates).strip('[]')        

【讨论】:

    【解决方案2】:

    当你找到答案时,你需要在你的while之外break

    【讨论】:

    • 这没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。
    • 相反。问题是“为什么我对项目 euler 3 的回答不起作用?”。他详细说明他的程序在 29 处进入无限循环。这是因为他没有跳出他的 while 循环。
    【解决方案3】:

    print num 声明之后,您不是incrementing 'x'

      for i in xrange (2,num):
          if num % i == 0:
             break
          else:
             print num
      x += 1
    

    你甚至应该可以去掉下面的第二个 if 语句

    getal = 13195
    x = 2 
    while x in xrange(2,getal):
      if getal % x == 0:
          num = getal / x
          for i in xrange (2,num):
              if num % i == 0:
                 break
              else:
                 print num
      x += 1
    

    【讨论】:

      【解决方案4】:

      答案是 6857。您不必从 2 到数字检查。使用素数的属性。只检查到您正在检查的数字的平方根。您可以使用我的 Java 代码作为参考。

      class p3{
      public static boolean isprime(long y){
          double sq = Math.sqrt(y);
          long endl =(long) (sq+.5);
          for(long j = 2;j <=endl ;j++)
          {
              if(y%j==0){
              return false;
              }
          }
          return true;
      }
      
      public static void main(String []asd){
          long test = 600851475143L;
          long ans =-1;
          double e = Math.sqrt(test);
          long end = (long)(e+1);
          for(long i = 2 ; i <= end ;i++)
          {
      
              if(test%i==0){
                  boolean val = isprime(i);
                  if(val){
                  ans = i;
                  }
              }
          }
          System.out.println(ans);
      }
      }
      

      如果您需要任何帮助。我已经解决了 Project Euler 中的问题,并将它们保存在我的 github 存储库中。非常欢迎你分叉它。网址是: https://github.com/vatsarahul999/ProjectEuler-.git

      在 python 中编写相同的代码。

       def isprime(n):
         if n < 2:
           return False
        if n == 2: 
          return True    
      
        if not n & 1: 
          return False
      
         for x in range(3, int(n**0.5)+1, 2):
            if n % x == 0:
              return False
         return True
      

      现在是主程序

      v = 13195
      x = 2
      while(x*x <= v)
        if(isprime(x)):
             a = x
             while(v%x==0)
                 v=v/x;
        x++
        print a
      

      【讨论】:

        【解决方案5】:

        这是一个示例(在性能方面可以改进):

        import math
        
        getal = 600851475143
        
        def prime(number):
            for i in xrange(2, int(math.sqrt(number)) + 1):
                if (number % i) == 0:
                    return False
            return True
        
        def prime_factors(number):
            ret = []
            n = number
            primes = []
            for i in [item for item in xrange(2, int(math.sqrt(n)) + 1)]:
                if prime(i):
                    primes.append(i)
            for i in primes:
                while n % i == 0:
                    ret.append(i)
                    n = n / i
            return ret
        
        print prime_factors(getal)
        

        【讨论】:

          【解决方案6】:

          为什么每个人都在递增以找到最大的数字?减少!!!

          def largestPrime(num):
            from __future__ import division
            for i in xrange(num//2 + 1, 1, -1):
              if num%i == 0 and all([i%j != 0 for j in range(2,i//2 + 1)]):
                return i
          

          【讨论】:

            【解决方案7】:

            你太复杂了,要了解所有因素

            getal = 13195
            for x in range(2, getal):
                if getal % x == 0:
                    print x
            

            这个应该使用 for 循环而不是一段时间, 在这里使用一段时间会是这样的

            getal = 13195
            x = 2
            while x < getal:
                if getal % x == 0:
                    print x
                x += 1
            

            你不需要遍历约束来在循环级别完成工作 - 因为你是在里面做的

            【讨论】:

            • 这不起作用:它打印所有因子,但问题是打印素因子。
            • 为什么投反对票 - 答案是帮助解决提问者编码的问题,而不是开发完整的算法
            • 啊……明白了。算法问题较多;我已经完成了一部分,但我想我会放弃它,因为原版有一个致命的缺陷。谢谢你的解释。
            【解决方案8】:

            您实际上非常接近得到正确答案,您只需删除 else 语句中的缩进即可获得 for else 块:

            >>> x = 2
            >>> getal = 13195
            >>> while x in range(2,getal):
                    if getal % x == 0:
                        num = getal // x
                        for i in range (2,num):
                                if num % i == 0:
                                    x += 1
                                    break #this will break for loop
                        else:#this is the only change, moving the else from an else inside of the for to a for else block
                                print (num)
                                break this will break while loop
                    else: 
                        x += 1
                        continue
            
            
            29
            

            这对大多数人来说是令人惊讶的,因为for-else 语句并不为人所知,但这几乎意味着只有在 for 块没有中断退出时才运行 else 块。

            考虑到这一点,是的,此代码有效,但正如许多其他人所说,这不是完成此任务的最佳方式。因为@RahulVasta 已经发布了足够好的答案,所以我不会。这并不是说你的逻辑不起作用,而是因为这是编程,所以有无数种方法可以解决问题,有些方法比其他方法更好。

            【讨论】:

            • 请注意,getal = 600851475143 必须使用 xrange
            • 是的,我根本不建议这样做,因为它的数字太大了编辑:这是 python 3,原来是 python 2!
            • 建议使用 for-else 似乎是一种让新手程序员感到困惑而不是帮助他们的秘诀。
            • 如果这是投反对票的原因,我将不得不不同意你的看法。是的,考虑到奇怪的语法,for-else 循环不是大多数新手程序员需要使用或应该真正使用的结构,但我确实建议找到另一种方法来完成这项工作。代码可以运行,尽管速度很慢,并且以易于理解的方式解释了 for-else 循环的用法。
            • 非常感谢您的回答。我通过将范围更改为 xrange 来编辑 R Nar 的答案,它适用于 13195。但是当我使用 600851475143 时它不起作用。我在 macbook pro 上的终端中运行程序。我知道这可能是一个艰难的计算,即使对于计算机也是如此,但它应该在几秒钟后给出一个解决方案,对吧?有谁知道为什么没有?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-30
            • 1970-01-01
            • 1970-01-01
            • 2022-01-07
            • 1970-01-01
            • 2020-12-27
            相关资源
            最近更新 更多