【问题标题】:Calculate all possible factors of a prime计算素数的所有可能因数
【发布时间】:2011-01-24 12:16:47
【问题描述】:

正在阅读 Python 教程并遇到了一个检查数字是否为素数的示例。我更改了一些内容,以便结果会显示数字的所有可能因素的列表,如果数字不是素数,但是,代码不起作用。

代码:

def isprime(number):
    print "Reticulating Splines..."
    fnum=[1,]
    notprime=0
    for p in range(2, number):
        if (number % p) == 0:
            notprime=1
            fnum.append(p)
            continue
        if notprime == 1:     
            return number, "is not a prime because of these factors", fnum  
        else:
            return True
num =int(raw_input("Enter number: "))
print isprime(num)

输出:

Enter number: 12
Reticulating Splines...
(12, 'is not a prime because of these factors', [1, 2, 3, 4])
>>> 
Enter number: 25
Reticulating Splines...
(25, 'is a prime number')

预期输出:

Enter number: 12
Reticulating Splines...
(12, 'is not a prime because of these factors', [1, 2, 3, 4, 6])

Enter number: 25
Reticulating Splines...
(25, 'is not a prime because of these factors', [1,5])

我的猜测是控制结构不佳,但有人可以修复我的代码吗?

我了解 range() 的工作原理:在这种情况下,range() 被赋予一个开始和一个停止值,step 默认为 1。我了解 continue,继续循环,但我可以将它与 if 一起使用吗?我认为这是错误的。

更新
已解决,缩进问题 continue 应该是 for 循环,同上 是 if...notprime。

def isprime(number):
    print "Reticulating Splines..."
    fnum=[1,]
    notprime=0
    for p in range(2, number):
        if (number % p) == 0:
            notprime=1
            fnum.append(p)
    if notprime == 1:     
        return number, "is not a prime because of these factors", fnum  
    else:
        return number, "is a prime number"
num =int(raw_input("Enter number: "))
print isprime(num)

更新 2:(感谢 @neil)
continue 简直是愚蠢的

更新了 n/2 和 sqrt(n) 之间的代码和速度比较 感谢@neil 和@emmanuel
n/2 代码:v2

import time
def isprime(number):
    start=time.clock()
    print "Reticulating Splines..."
    fnum=[1,]
    notprime=0
    for p in range(2, (number/2)+1):
        if (number % p) == 0:
            notprime=1
            fnum.append(p)
    end=time.clock()
    if notprime == 1:     
        return number, "is not a prime because of these factors", fnum, "Time taken", end-start  
    else:
        return number, "is a prime number. Time Taken", end-start
print "Prime or factor calculator v2 using n/2"
print #
num =int(raw_input("Enter number: "))
print isprime(num)

sqrt(n) 代码:v3

import math, time
def isprime(number):
    start=time.clock()
    print "Reticulating Splines..."
    fnum = [1,]
    last = int(math.ceil(math.sqrt(number)))
    for p in range(2, last + 1):
        if (number % p) == 0:
            fnum.append(p)
            fnum.append(number / p)
    # Remove duplicates, sort list
    fnum = list(set(fnum))
    fnum.sort()
    end=time.clock()
    if len(fnum) > 1:     
        return number, "is not a prime because of these factors", fnum ,"Time taken", end-start 
    else:
        return True, "Time taken", end-start

print "Prime or factor calculator v3 using sqrt(n)"
print #

num =int(raw_input("Enter number: "))

print isprime(num)

输出(只显示时间)

sqrt(n) 代码的时间:v3
使用 sqrt(n) 的素数或因子计算器 v3
输入号码:999999
所用时间',0.0022617399697466567

n/2 代码的时间:v2
使用 n/2 的质数或因子计算器 v2
输入号码:999999
耗时:0.11294955085074321

原始代码时间(n):v1
素数或因子计算器 v1
输入号码:999999
耗时:0.22059172324972565

v1 和 v2 无法处理数字 999999999、999999999999 和 999999999999999,都给出了 MemoryError

但是 v3 处理了这三个数字:
999999999 : 0.010536255306192288
999999999999 : 0.75631930873896636
999999999999999:24.04511104064909

shell 挂起 9999999999999999 并为 999999999999999999 提供 MemoryError

感谢@Lennart,我正在考虑通过使用类以更OOP 友好的方式重写代码。但我似乎做得不对。

【问题讨论】:

  • 主题:“计算素数的所有可能因子”。假设素数是p,那么因子和1和p
  • @abel 可能会有所帮助,但我想这个问题解释了它。我只是觉得这很有趣 - 找到素数的因数非常容易!
  • 代码清晰。你不应该担心在你的阶段打字速度。
  • 而且,顺便说一下,我并不是说你以后会更关心打字速度:代码清晰总是更重要的。 (尽管有经验,“变得”清晰的代码范围更大。)尤其是当您学习基本概念时,打字本身应该不那么重要了。
  • @abel 如果你写代码的时间比读代码的时间多,那你就错了!

标签: python primes


【解决方案1】:

问题是你的缩进 - if notprime==1: 不应该在 for 循环中。它应该只有一级缩进。

另外,continue 是不必要的。

编辑:

你可以做的一个改进(我昨晚刚刚为一个 Project Euler 问题研究素数)是只循环到 n/2 - 不能有一个大于一半数字的因子。

【讨论】:

  • 有没有办法将其转换为 lambda 函数?我通过将 `for p in range(2, number):` 更改为 for p in range(2, (number/2)+1): 来实现 n/2
【解决方案2】:

你最后的if notprime ... 和它后面的三行缩进太远,因此在循环内部而不是外部执行。

【讨论】:

    【解决方案3】:

    您只测试了一个数字后返回。将 if 测试和返回移到 for 循环之外。

    此外,如果它是素数则返回True,如果不是,则返回字符串是不切实际的。 如果你再打电话

    if isprime(7):
    

    这将始终评估为 True。我做了一些改进:

    def factors(number):
        fnum=[]
        for p in range(2, number):
            if (number % p) == 0:
                fnum.append(p)
        return fnum
    
    for x in range(100):
        f = factors(x)
        if f:
            print x, "is not a prime and has factors", f
        else:
            print x, "is a prime"
    

    【讨论】:

      【解决方案4】:

      @尼尔:

      “您可以做出的改进......是只循环到 n/2 - 不能有一个大于一半数字的因子。”

      顺便说一下,你需要测试的最高值是int(math.ceil(math.sqrt(n))),不需要去n/2,如果每次得到一个值,你都会得到关联的(即如果a x b = n,要么是@987654324 @或b小于n的平方根,另一个大于):

      def isprime(number):
          print "Reticulating Splines..."
          fnum = [1,]
          last = int(math.ceil(math.sqrt(number)))
          for p in range(2, last + 1):
              if (number % p) == 0:
                  fnum.append(p)
                  fnum.append(number / p)
          # Remove duplicates, sort list
          fnum = list(set(fnum))
          fnum.sort()
          if len(fnum) > 1:     
              return number, "is not a prime because of these factors", fnum  
          else:
              return True
      

      更高的性能,即使最后列表没有排序(但这可以通过在良好的索引处添加两个数字 pnumber / p 在循环内完成)。

      【讨论】:

      • 发布了使用您的方法与 n/2 之间的比较
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-23
      • 1970-01-01
      • 2013-03-21
      • 1970-01-01
      • 2022-11-24
      • 2014-10-16
      • 2017-02-02
      相关资源
      最近更新 更多