计算素数的所有可能因子

时间:2011-01-24 12:16:47

标签: python primes

正在阅读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()被赋予一个开始和一个停止值,步骤默认为1.我知道继续,继续一个循环,但是我可以使用if吗?我认为这是错误的。

更新
解决了,缩进的问题,对于if循环,应该是for循环,ditto

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)

Update2:(Thx to @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
Prime或因子计算器v3使用sqrt(n)
输入数字: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方式重写代码。但我似乎并没有做得对。

4 个答案:

答案 0 :(得分:1)

您的最终if notprime ...及其后面的三行缩进太远,因此在循环内执行,而不是在外部执行。

答案 1 :(得分:1)

只测试一个号码后返回。将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"

答案 2 :(得分:1)

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

此外,continue是不必要的。

编辑:

你可以做的一个改进(我昨晚刚刚为一个项目欧拉问题处理素数)只是循环到n / 2 - 不能超过数字的一半。

答案 3 :(得分:1)

@neil:

  

“你可以做出的改进......只能循环到n / 2 - 不能超过数字的一半。”

顺便说一下,您需要测试的最高值为int(math.ceil(math.sqrt(n))),如果每次获得值,则无需转到n/2,您将获得相关的值(即{{1} } {} a x b = na低于n的平方根,另一个更高):

b

性能更高,即使最后列表没有排序(但这可以通过在好的索引处添加2个数字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 p在循环内部完成)。