Python函数template Python函数判断素数_Python函数template


【本文结构】

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

【题目信息】


描述:判断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之间
取余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)

【斩获成果】

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

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

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

举一反三,抛出问题:

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