用matlab寻找第n个默尼森数,python之寻找第n个默尼森数-续

上一篇博客讲到python之寻找第n个默尼森数,在课程讨论区看到一位同学的提问,觉得可以巩固一下知识,将问题和讲解总结在这里。

1.问题原地址与源代码

问题点这里

(课程关闭后可能打不开)

该同学的代码

def prime(num):

for i in range(2,num//2):

if (num % i)==0:

return False

else:

return True

def monisen(no):

b=[2]

i=2

while len(b) < no:

if prime(i) and prime(2**i-1):

b.append(2**i-1)

i +=1

else:

i+=1

print(b[-1])

print(monisen(int(input())))

标准输入为4的时候,执行后的结果是这样的

31

None

2.分析

首先,第一个问题看输出很明显也很容易改,因为输出有两个而要求只是一个,再仔细看下代码发现第二个函数monisen里已经出现了print函数,这时候再对函数进行print当然是没有输出显示None了。只要将print改成return即可。

然后一个问题稍微复杂一点,回想一下默尼森数应该是[3,7,31,127…]这样的一组数,所以当输入为4的时候输出应该是127。而此时输出为31,显然不对。再看代码,发现默尼森数的列表b中最先加进了2这个数,这时候发现问题,加进去的应该是3而不是2,同时开始的i应该置为3(第二个素数)而不是2。

3.修改代码

def prime(num):

for i in range(2,num//2):

if (num % i)==0:

return False

else:

return True

def monisen(no):

b=[3]

i=3

while len(b) < no:

if prime(i) and prime(2**i-1):

b.append(2**i-1)

i +=1

else:

i+=1

return b[-1]

print(monisen(int(input())))

4.继续修改

上面3的代码已经可以通过一般的测试了,也确实通过了MOOC的测试用例的考察。是对该同学代码改动最少的版本。但是其实这段代码还是有问题的,列举如下。

i从3开始迭代,也就意味着要执行prime(3), prime(4)…而在prime函数中,使用了range作为迭代对象,当num//2 <=2时,也就是i为3和4时,因为range上界小于等于下界,所以是进不去for循环的。这样就会导致prime(4)输出结果为True,也就是给出判断4是素数。

然后看到判断素数那个函数里面else不是跟if对齐而是跟for对齐的,这个苦恼了很久。而测试了几个执行结果都是正确的。

先解决第二个问题,经过查询发现真的是有for else语句的,但是要注意有一个坑,就是当for全部迭代完的时候,无论if语句里面是不是真,else都会执行,所以在一般的使用中需要在if语句中加break语句使之跳出可以避免执行else语句。

详细参考Python中for循环搭配else的陷阱

(在本例中因为return就直接跳出了所以不会出现问题。)

第一个问题就靠分类讨论,将其分离出来单独处理。

5.再次修改后的代码

import math

def prime(num):

for i in range(2,int(math.sqrt(num))+1):

if (num % i)==0:

return False

return True

def monisen(no):

b=[3,7]

i=5

while len(b) < no:

if prime(i) and prime(2**i-1):

b.append(2**i-1)

i +=1

else:

i+=1

return b[-1]

print(monisen(int(input())))

顺便把上界也改小了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值