鱼C-小师妹 发表于 2021-7-24 17:59:59

16 - 数之吟唱:素数

本帖最后由 鱼C-小师妹 于 2021-9-7 14:41 编辑

在线视频:

https://www.bilibili.com/video/BV1HT4y1K7DY?p=18

https://xxx.ilovefishc.com/forum/202105/31/204333obvdca8ankppcn9v.png.thumb.jpg

素数相信很多鱼油都不陌生啦,这一讲我们来看如何找出自定义范围内的素数。

算啦,素数概念还是要说下:

只能被1和它自身整除的整数
判定一个整数 a 是否为素数的关键,就是要判定整数 a 能否能被除 1 和它自身以外的其他任何整数所整除。

若都不能整除,则 a 为素数。

这次我们求的是给定范围 start~end 之间的所有素数。

考虑学到这一讲的童鞋能力都有所提升,我们就从程序通用性角度来设计算法。

既然是自定义范围,那就需要从键盘输入 start 和 end 的值。

例如输入 start=1,end=2333,则所编写的程序应能够打印出1~2333 之间的所有素数。

那种直觉应该有了,像这种找数字的题,往往都会用到“n 层循环结构”。

还记得我们在百钱百鸡优化循环的操作吗。

利用条件间的相互关系缩小不同层级间的循环范围。

既然我们考虑用双层循环结构实现,外层循环对 start~end 之间的每个数进行迭代,逐一检查其是否为素数。

外层循环的循环变量用变量 m 表示,m 即代表当前需要进行判断的整数,显然其取值范围为 start≤m≤end 。

内层循环稍显复杂,完成的功能是判断当前的 m 是否为素数。

我们可以设内循环变量为 i,程序设计时 i 从 2 开始,直到约束条件 m1/2 为止。

为什么到 m1/2 而不是 end 就可以了呢?!

这就要涉及到另一种数:“合数”,它是指在大于 1 的整数中除了能被 1 和本身整除外,还能被其他数(0 除外)整除的数。

而合数可以拆成两个因数相乘,这两个因数一定一个小于等于(和数)1/2,一个大于等于(和数)1/2。
(注:m1/2 即对 m 开根号)

这个理论就不在课堂上证明了,肯定没问题~

就拿 16 举例子,(16)1/2 为 4,所有因子相乘情况:

2 * 8
4 * 4
8 * 2
如果是非素数 m ,那么在 m1/2 前一定存在一个被除数,就没必要继续往下循环咯~

用 i 依次去除需要判定的整数 m,如果 m 能够被 2~ m1/2 中的任何一个整数所整除。

可以确定当前的整数 m 不是素数,因此应提前结束该次循环。

如果 m 不能被 2 ~ m1/2 中的任何一个整数所整除,就表示 m 是素数。

我们还可以创建个标志位 flag 来监控内外循环执行的情况。

将 flag 初值设为 1,在内层循环中判断时,如果 m 能够被 2 ~ m1/2 中的任何一个整数所整除,则在内循环中将 flag 设置为 0 。

如果 m 不能被 2 ~ m1/2 中的任何一个整数所整除,则在内循环中不会修改 flag 标志的值,退出内循环后它的值仍为 1。

此时在外循环中对 flag 的值进行判断,如果 flag=0,则显然当前的 m 不是素数。

如果 flag=1,则当前的 m 是素数,应该将其打印出来。

还需要注意的是,在外循环中,每次要进行下一次迭代之前,要先将 flag 标志再次置为 1。

在设计算法时我们还可以定义 count 变量用来保存最后求得的 start~end 之间素数的总个数。

将上面的算法转成流程图(自己去画,然后来对答案哈):

**** Hidden Message *****

俗话说得好:

做好流程图,程序立刻出~
先来搞定输入 start 和 end 并判断输入是否合法。

输入 start 和 end 值,并使用 while 语句来判断 start 和 end 的值是否满足条件 start>0 且 start<end 。

如果满足则输入范围合法,否则重新输入:

print("请输入一个整数范围(起start-终end): ")
start = int(input("start = "))
end = int(input("end = "))
while not (start > 0 and start < end):
    print("输入的参数有误!快给我重新输入:")
    start = int(input("start ="))
    end = int(input("end = "))
现在来进入核心阶段求素数,一开始说了使用双循环求指定范围内的素数。

外层循环,对 start~end 之间的每个数进行迭代,检查是否为素数:

m = start
while m <= end:
    k = math.sqrt(m)
    i = 2
   while i <= k:
      # 内层循环
      i += 1
    m += 1
使用 math.sqrt() 方法需要导入 math 模块:

import math
内层循环,判断 2~k 之间的每个数是否能被 m 整除。

若存在一个数能被 m 整除,则跳出内层循环。

否则,m 是素数,打印 m:
while i <= k:
      if m % i == 0:
            flag = 0
            break
      i += 1
打印的数字如果很多,我们还是要换行处理,那就 16 个来换行一次:

if flag == 1:
      print(m, end=" ")
      count += 1
      if count % 16 == 0:
            print()
    flag = 1
    m += 1
核心代码都搞定啦,完整代码就是你们的课后作业啦。



源码:

就酱紫,下课!

小月yyds 发表于 2021-7-24 18:53:12

{:5_105:}

柿子饼同学 发表于 2021-7-24 20:46:13

{:7_146:}

李姐万岁 发表于 2021-7-24 22:18:02

小师妹,加油哦

hornwong 发表于 2021-7-25 21:32:09

{:5_95:}

jinhuaedu 发表于 2021-8-24 15:26:30

OK,打酱油来啦

Debug007 发表于 2021-9-17 09:49:57

我爱鱼c

LyyLD 发表于 2021-11-4 14:47:34

{:5_102:}

游刃鱿鱼 发表于 2021-11-9 16:46:21

count = 0
start = int(input('指定开始的数:'))
stop = int(input('指定结束的数:'))
for i in range(start,stop+1):
    for n in range(2,i):
      ifi % n == 0:
            break
    else:
      if count % 6 == 0:
            print( )
      else:
            print(',',end='')
      print(f"{i}是素数",end='')
      count += 1


print(f'\n{start}到{stop}之间共有{count}个素数')

tucc 发表于 2022-1-5 20:29:56

。。

张亚当 发表于 2022-2-18 03:04:20

{:5_90:}

CG2022 发表于 2022-3-9 20:36:28

{:10_254:}

投入就放过 发表于 2022-3-16 14:28:03

a

Hyjxsssss 发表于 2022-5-9 13:31:24

# 题干
# 判定一个整数 a 是否为素数的关键,就是要判定整数 a 能否能被除 1 和它自身以外的其他任何整数所整除。
# 这次我们求的是给定范围 start~end 之间的所有素数

# 首先判断一个数字是不是素数
# 再外层叠加循环

start = int(input('start = '))
end = int(input('end = '))
print('%d - %d 中的素数为:' % (start, end))
count = 0
for n in range(start, end + 1):
    factorstorage = []
    for i in range(2, n):
      if n%i == 0:
            factorstorage.append(i)
            break
    if len(factorstorage) == 0:
      count += 1
      if count%5 != 0:
            print(n, '\t', end = '')
      else:
            print(n)
print('\n经统计 %d - %d 中共有 %d 个素数' % (start, end, count))

语与余 发表于 2022-11-14 19:16:20

import math
count = 0
start = int(input('start的数值:'))
end = int(input('end的数值:'))
for i in range(start,end+1):
    for j in range(2,int(math.sqrt(i))+1):
      if i % j == 0:
            break
    else:
      count +=1
      print(i,end=' ')
      if count % 16 == 0:
            print()
print(f'\n总共有{count}个素数')
   

Alexiiis 发表于 2023-6-5 22:21:25

沙发

pingkong 发表于 2023-11-2 09:19:39

学习一下下

wk012233 发表于 2023-11-2 14:48:42

学习
页: [1]
查看完整版本: 16 - 数之吟唱:素数