python判断素数_Python解题记录第12题

35e3008871c5b876265a64d360df16ab.png

【本文结构】

  1. 题目信息:来源、地址、序号、描述
  2. 题目答案:简要分析,程序代码(测试运行通过,含注释),运行结果
  3. 霍霍磨刀:解答这道题目之前应掌握的知识基础
  4. 解析过程:题目类型,分析以及实践过程
  5. 斩获成果:通过解答这道题目之后的知识提升
  6. 下一题预告:来源、地址、序号、描述

【题目信息】

来源:菜鸟教程

地址:https://dwz.cn/Ol2QUMGD

序号:12

描述:判断101-200之间有多少个素数,并输出所有素数

【题目答案】

程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。

程序代码(菜鸟教程上的答案):

h = 0 # 定义变量h,并赋初值为0,计算素数总数
leap = 1 # 定义变量leap,并赋初值为1,作为标记,判断是否为素数from math import sqrt # 从math库中导入sqrt函数:开平方from sys import stdout # 从sys库中导入stdout函数:输出for m in range(101,201): # 循环101到200之间
k = int(sqrt(m + 1)) # 开平方并取整for i in range(2,k + 1): # 循环2到开方数if m % i == 0: # 如果取余为0
leap = 0 # 那么设置变量leap为0break # 跳出循环if leap == 1: # 如果变量为1
print('%-4d' % m) # 输出素数
h += 1 # 素数数量加1if h % 10 == 0: # 如果数量为10的倍数
print() # 则输出空行
leap = 1 # 恢复leap标记为1
print('The total is %d' % h) # 输出素数总数为h

运行结果:

101

103

107

109

113

127

131

137

139

149

151

157

163

167

173

179

181

191

193

197

199

The total is 21

【霍霍磨刀】

在解答这道题目之前,你首先应具备以下知识基础:

  1. for循环结构的使用
  2. 素数的概念,素数举例

【解析过程】

题型:{语法描述题}

  1. 解题(分步实施)
    1. 如何用程序来判断一个数是素数

判断一个数是不是素数,用该数逐个除以比它小的数,如果能整除,则不是素数,否则就是素数,代码如下:

flag=1 # 定义变量flag,赋初值为1,用于判断是否为素数,1:素数,0:不是素数
n=int(input("请输入一个数:")) # 输入一个数for i in range(2,n): # 循环2到该数之间的数if n % i==0: # 依次判断取余是否为0
flag=0 # 如果可以取余为0,则设置标记为0break # 跳出循环if flag==1: # 如果标记为1
print("{}是素数".format(n)) # 则该数为素数else: # 否则
print("{}不是素数".format(n)) # 该数不是素数

  1. 如果循环100到200之间的数

循环100到200,我们可以采用for结构和range函数

for i in range(101,201):

  1. 如何找出100到200之间的素数

将上述代码合并到一起,也就是把判断素数的代码放到100到200的循环之间,代码如下所示

flag=1 # 定义变量flag,赋初值为1,用于判断是否为素数,1:素数,0:不是素数

for i in range(101,201): # 外循环,循环101到200之间

for j in range(2,i): # 内循环,循环2到i之间

if i % j ==0: # 判断i取余j是否为0

flag=0 # 如果为0,则标记flag为0,该数不是素数

break # 跳出内循环

if flag==1: # 如果flag为1,则为素数

print(i) # 输出该数

flag=1 # 重置flag标记为1

  1. 如何统计素数总数

定义一个变量n,每次找到一个素数,变量n加上1,即可,代码如下

flag=1 # 定义变量flag,赋初值为1,用于判断是否为素数,1:素数,0:不是素数
n=0 # 定义变量n,赋初值为0,用于统计素数总数for i in range(101,201): # 外循环,循环101到200之间for j in range(2,i): # 内循环,循环2到i之间if i % j ==0: # 判断i取余j是否为0
flag=0 # 如果为0,则标记flag为0,该数不是素数break # 跳出内循环if flag==1: # 如果flag为1,则为素数
print(i) # 输出该数
n+=1 # 素数数量加1
flag=1 # 重置flag标记为1
print("101到200之间的素数总数为:",n) # 输出素数总数为n

解答完毕

  1. 优解(优化解题)

经过上述的解答,基本答案已经出来,但从编程学习角度来讲,我们还可以进行优化

  1. 关于遍历次数

修改上述代码,加入一个变量p,用来统计两次循环下的运行次数,代码如下所示:

flag=1 # 定义变量flag,赋初值为1,用于判断是否为素数,1:素数,0:不是素数
n=0 # 定义变量n,赋初值为0,用于统计素数总数
p=0 # 记录遍历次数for i in range(101,201): # 外循环,循环101到200之间for j in range(2,i): # 内循环,循环2到i之间
p+=1 # 遍历次数加1if i % j ==0: # 判断i取余j是否为0
flag=0 # 如果为0,则标记flag为0,该数不是素数break # 跳出内循环if flag==1: # 如果flag为1,则为素数
print(i) # 输出该数
n+=1 # 素数数量加1
flag=1 # 重置flag标记为1
print("101到200之间的素数总数为:",n) # 输出素数总数为n
print("遍历次数为:",p) # 输出遍历次数

在运行结果中,可以看到:

遍历次数为: 3291

而在网站提供的答案代码的相同位置加上p,代码如下:

h = 0 # 定义变量h,并赋初值为0,计算素数总数
leap = 1 # 定义变量leap,并赋初值为1,作为标记,判断是否为素数
p=0from math import sqrt # 从math库中导入sqrt函数:开平方from sys import stdout # 从sys库中导入stdout函数:输出for m in range(101,201): # 循环101到200之间
k = int(sqrt(m + 1)) # 开平方并取整for i in range(2,k + 1): # 循环2到开方数
p+=1if m % i == 0: # 如果取余为0
leap = 0 # 那么设置变量leap为0break # 跳出循环if leap == 1: # 如果变量为1
print('%-4d' % m) # 输出素数
h += 1 # 素数数量加1if h % 10 == 0: # 如果数量为10的倍数
print() # 则输出空行
leap = 1 # 恢复leap标记为1
print('The total is %d' % h) # 输出素数总数为h
print("遍历次数为:",p) # 输出遍历次数

运行结果却是:

遍历次数为: 392

这是什么原因呢,其实与内循环的素数判断代码的范围不一致有关,回到如何判断是素数上来看,如何判断一个数是素数,我们一般是这么理解,将该数除以比它小的数,如果都无法整除,则该数是素数,其实没必有一直去除,只需要除到一定的数即可,那这个数是多少,是它的开方数

举个例子,判断13是否是素数,我们写一段代码,如下所示

n=13for i in range(2,n):
print("{}//{}={}".format(n, i, n//i))

运行结果:

13//2=6

13//3=4

13//4=3

13//5=2

13//6=2

13//7=1

13//8=1

13//9=1

13//10=1

13//11=1

13//12=1

它的被除数和商中总有一个数在它的开方数以下,也就是换句话说,当13除以3无法进行整除的话,那么后续的除法其实都是没有必要的,做的是无用功。

因此,我们引入math库中的sqrt函数,改动内循环的最高值,代码如下

from math import sqrt # 从math库中导入sqrt函数:开平方
flag=1 # 定义变量flag,赋初值为1,用于判断是否为素数,1:素数,0:不是素数
n=0 # 定义变量n,赋初值为0,用于统计素数总数
p=0 # 记录遍历次数for i in range(101,201): # 外循环,循环101到200之间
k = int(sqrt(i)) # 开平方并取整for j in range(2,k+1): # 内循环,循环2到i之间
p+=1 # 遍历次数加1if i % j ==0: # 判断i取余j是否为0
flag=0 # 如果为0,则标记flag为0,该数不是素数break # 跳出内循环if flag==1: # 如果flag为1,则为素数
print(i) # 输出该数
n+=1 # 素数数量加1
flag=1 # 重置flag标记为1
print("101到200之间的素数总数为:",n) # 输出素数总数为n
print("遍历次数为:",p) # 输出遍历次数

运行结果中:

遍历次数为: 392

可以看到运行次数大幅减少,运行效率大幅提升

  1. 关于输出显示

print(i) # 输出该数

修改为

print(i,end=",") # 输出该数

将每行一个的显示改为逗号分割,可方便查看

  1. 采用过滤函数filter来实现找素数

在一段数当中找到符合条件的数,其实我们可以利用python中的高阶函数filter函数来实现,实现代码如下

def is_prime(n):for s in range(2, n):if n % s == 0:return False return True
tmplist = filter(is_prime,range(101,201))
newlist = list(tmplist)
print(newlist)

# 该代码参考学习了廖雪峰的官方网站内的对filter函数的描述,做了简单的修改# https://www.liaoxuefeng.com/wiki/1016959663602400/1017404530360000


【斩获成果】

这题在编程中属于基本的语法结构和对数学定义的理解题,偏简单型,在曾经vb的教学过程中,对于定义一个flag无法理解,其实我们把它理解为一个开关,一个标记,一个符合条件的球都可以。

通过这题的学习,我们学会了如何更好地去找出素数,并尝试探索了高阶函数filter的运用。

解决这样的程序,可以通过先遍历,再判断的方式来解决。

举一反三,抛出问题:

  1. 找出100到200之间能被7整除的数
  2. 找出100到200之间中带数字3的数字

【下一题预告】

来源:菜鸟教程

地址:https://dwz.cn/Ol2QUMGD

序号:13

描述:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方

我的公众号:Python解题(mygkk123),欢迎关注

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值