zoukankan      html  css  js  c++  java
  • 例子:循环语句--素数问题

    例子1:判断一个数是不是素数。

    首先要了解该题目的意思,什么是素数?除了1和自身能被整除之外,其他数字都不能被整除的数为素数。

    方法一:

    那么我们可以根据素数的定义来展开程序的构造,1和自身能被整除,假如此数为n,1~n这个范围中可以将1和n视作两个边界,其中的数都不被整除即可,这样的话我们可以使用range()函数和%取模运算来展开代码。

     1 # coding=gbk
     2 while True:
     3  n = int(input("请输入一个整数:"))
     4  if n < 2:
     5    print(str(n),"不是素数也不是合数!")
     6  else:
     7    for i in range(2,n):
     8      m = n % i
     9      if m == 0:
    10        print(str(n),"不是素数!")
    11        break
    12      else:
    13        print(str(n),"是素数!")

    1是一个边界,做特殊处理,4~5行代码。被除数从2开始算起,range()函数含左不含右,使用for循环挨个去小于n的正整数,n对其一次取模与0作比较,若等于0,进入if,输出不是素数且break终止循环,若不等于0,直接进入else,输出是素数。

    在这里要注意一个问题,如下图所示:

    程序里的第二个else不是和第二个if一起搭配的,如果写成图中所示,那么会出现错误,9、15等数会显示是素数,但是9、15这些数是会被3和5整除的。那么这个错误是怎么出现的呢?假如n=9,那么,进入for循环后,i取2,9%2不等于0,因此会进入else输出是素数,也就意味着i在range()函数里不会继续走下去,不会继续等于3~8,自然不会有9%3这种判别。因此,上图中的第二个else完全是没有意义的。必须让i遍历完所有的数,被n取模运算后,才能得出是不是素数的结论。

    方法二:

    第一种方法,逻辑思维很简单,但是如果是一个很大的数值,从2开始逐个寻找被除数,代码的运行速率会明显得降低,那么,我们可以将方法一中的代码进行优化处理。

     

    黄色框之内的代码就是优化代码,(n**0.5)+1是对n开方+1,+1的意思是保证有些数开方后的余数可以进1,这里range()函数的取值范围就比第一种方法小得多,运行起来也效率高的多。(n**0.5)+1的前面要记得加上int(),因为这里是整数运算,开方后的数值类型为浮点数,要取其整数部分。

    例子2:列出10万以内的所有素数。(这里考验的是程序的效率问题)

    该例子可以使用例子1中的代码进行修改,如下图所示,这里用到了计时模块,可以看出该代码的运行时间为3.73秒

     1 # coding=gbk
     2 num = int(input('请输入你所需要的数值范围:'))
     3 print('该数值范围内的所有素数为:')
     4 import datetime
     5 # import datetime这里用到了计时模块
     6 start = datetime.datetime.now()
     7 # 开始计时,赋值给start
     8 for a in range(2,num):
     9     for b in range(2,int(a**0.5)+1):
    10         if a % b == 0:
    11             break
    12     else:
    13         print(a,end=' ')
    14 delta = (datetime.datetime.now() - start).total_seconds()
    15 # 结束计时,赋值给delta
    16 print()
    17 print(delta)
    18 
    19 # 第9行用到了开方的方法
    20 
    21 ##################################################
    22 D:untitledproject2venvScriptspython.exe D:/untitled/project2/day1/refefe.py
    23 请输入你所需要的数值范围:100000 
    24 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 …… 26 0.720588 27 28 Process finished with exit code 0
     1 # coding=gbk
     2 num = int(input('请输入你所需要的数值范围:'))
     3 print('该数值范围内的所有素数为:')
     4 print(2,end=' ')
     5 import datetime
     6 # import datetime这里用到了计时模块
     7 start = datetime.datetime.now()
     8 # 开始计时,赋值给start
     9 for a in range(3,num,2):
    10     for b in range(3,int(a**0.5)+1):
    11         if a % b == 0:
    12             break
    13     else:
    14         print(a,end=' ')
    15 delta = (datetime.datetime.now() - start).total_seconds()
    16 # 结束计时,赋值给delta
    17 print()
    18 print(delta)
    19 
    20 # 这里注意素数的性质,第9行代码里刨除了2这个特殊情况,以3开始,因为所有的偶数都不是素数,只看奇数即可。
    21 # 记得不要忽略2这个特殊情况,第4行代码
    22 ################################################
    23 D:untitledproject2venvScriptspython.exe D:/untitled/project2/day1/refefe.py
    24 请输入你所需要的数值范围:100000
    25 该数值范围内的所有素数为:
    26 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 ……
    27 0.62263 28 29 Process finished with exit code
    # 在这里其实还能进一步的进行代码的优化,将b的for循环的代码(第10行代码)更改一下,for b in range(3,int(a**0.5)+1):变成for b in range(3,int(a**0.5)+1,2):步长为2,这样的话,该代码的效率还会提升。
     1 # coding=gbk
     2 num = int(input('请输入你所需要的数值范围:'))
     3 print('该数值范围内的所有素数为:')
     4 print(2,3,end=' ')
     5 import datetime
     6 # import datetime这里用到了计时模块
     7 start = datetime.datetime.now()
     8 # 开始计时,赋值给start
     9 num = num - num%6
    10 for a in range(5,num,6):
    11     for b in range(2,int(a**0.5)+1):
    12         if a % b == 0:
    13             break
    14     else:
    15         print(a,end=' ')
    16     num = a + 2
    17     for b in range(2,int(a**0.5)+1):
    18         if num % b == 0:
    19             break
    20     else:
    21         print(num,end=' ')
    22 delta = (datetime.datetime.now() - start).total_seconds()
    23 # 结束计时,赋值给delta
    24 print()
    25 print(delta)
    26 # 这里利用了素数的一个特性,大于等于5的素数一定和6的倍数相邻,代码第9、10行
    27 # 要注意5前面的素数要额外输出,代码第4行
    28 ###############################################
    29 D:untitledproject2venvScriptspython.exe D:/untitled/project2/day1/refefe.py
    30 请输入你所需要的数值范围:100000
    31 该数值范围内的所有素数为:
    32 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67……
    33 0.614633 34 35 Process finished with exit code 0

    显示10万以内的素数的方法还有很多,通过上述的几种方法来看,减少遍历的数字是提高代码效率的根本,第二种方法只检索奇数,一下就少了很多的遍历次数,第三,四种方法每隔6个数遍历一次,也省略了很多的遍历次数。

  • 相关阅读:
    8、泛型程序设计与c++标准模板库5.函数对象
    Linux和Windows系统分区原理
    Linux命令----cd
    为什么会产生TCP/IP?
    区间 dp
    dp-划分数 (递推)
    dp-LCS(递归输出最短合串)
    dp-(LCS 基因匹配)
    位运算符
    求对数
  • 原文地址:https://www.cnblogs.com/linfengs/p/11585065.html
Copyright © 2011-2022 走看看