如何求解素数?

浏览: 824

给定一个正整数N,如何求解小于等于N的所有素数?

如:

输入:100

输出:2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

如何分析这个算法呢?如果要求不大于N的所有的素数,很明显思路应该是从1到N逐一检测是不是素数。

所以,伪代码可以写为:

N = int(input())
n = 2
while n <= N:
      if n is a prime number:
            print(n)
      n = n + 1

现在问题归结为判断一个数n是不是素数的问题,这样将一个大问题化解为小问题来进行求解,这是解决算法问题的一大思路。那么问题来了,该如何判定一个数是否是素数呢?

我们需要通过以下四步来完成:

1、先获取n的所有的可能的因子,即2,3,4,...,n-1;

2、检查n是否含有上述可能的因子;

3、若n含有上述因子,则n是合数;

4、若n不含有上述因子,则n是素数。

根据伪代码可以写出版本1代码:

n = int(input("Please type a positive integer, greater than 1: "))

factor = 2
isPrime = True

while factor < n:
if (n % factor == 0):
isPrime = False

   factor = factor + 1

if isPrime:
print(n, " is a prime.")
else:
print(n, " is a composite.")

这里,应用布尔变量isPrime表示一个数是否是素数。但是有什么优化的空间呢?

根据定义,我们知道,只要n具有2到n-1之间的一个因子,那么n肯定不是素数,也就是说,一旦发现n具有其中的一个因子,后续的循环是没必要的。怎么终止循环呢?程序中一般使用break关键字来结束循环。注意与continue关键字的区别,continue是结束本次循环而进行下一次循环,而break是终止for或者while循环。稍作修改,得到版本2的代码:

n = int(input("Please type a positive integer, greater than 1: "))

factor = 2
isPrime = True

while factor < n:
if (n % factor == 0):
isPrime = False
       break
   factor = factor + 1

if isPrime:
print(n, " is a prime.")
else:
print(n, " is a composite.")

但是还有什么优化的空间呢?我们知道,sqrt(n)*sqrt(n) = n,所以一旦n具有大于sqrt(n)的因子,必然有相对应的小于sqrt(n)的因子。那么,我们只需要检测2到sqrt(n)之间的所有因子。修改可得版本3的代码:

import math

n = int(input("Please type a positive integer, greater than 1: "))

factor = 2  # initial value of possible factor
isPrime = True  # variable to remember if n is a prime or not
factorUpperBound = math.sqrt(n) # the largest possible factor we need to test is sqrt(n)

# loop to generate and test all possible factors
while (factor <= factorUpperBound):
# test if n is evenly divisible by factor
   if (n % factor == 0):
isPrime = False
       break

   factor = factor + 1

# Output
if isPrime:
print(n, " is a prime.")
else:
print(n, " is a composite.")

代码还有一种实现方式,就是不在使用break而使用布尔类型的变量进行and来操作,得到版本4的代码:

# Programmer: Python那些事
# Date: April 14, 2017
# This program reads a positive integer, greater than 1 and
# determines whether this integer is a prime or not.

import math

n = int(input("Please type a positive integer, greater than 1: "))

factor = 2  # initial value of possible factor
isPrime = True  # variable to remember if n is a prime or not
factorUpperBound = math.sqrt(n) # the largest possible factor we need to test is sqrt(n)

# loop to generate and test all possible factors
while (factor <= factorUpperBound) and (isPrime):
# test if n is evenly divisible by factor
   if (n % factor == 0):
isPrime = False

   factor = factor + 1

# Output
if isPrime:
print(n, " is a prime.")
else:
print(n, " is a composite.")

现在,有了以上判定一个数是否素数的代码,可以回到主问题了,得到最终版本的代码了:

# Programmer: Python那些事
# Date: April 14, 2017
# This program reads a positive integer, greater than 1 and
# prints all the primes smaller than the integer.

import math

N = int(input("Please type a positive integer, greater than 1: "))

n = 2  # n will take on values from 2 through N and we will test each n for primality
while n <= N:
factor = 2  # initial value of possible factor
   isPrime = True  # variable to remember if n is a prime or not
   factorUpperBound = math.sqrt(n) # the largest possible factor we need to test is sqrt(n)

   # loop to generate and test all possible factors
   while (factor <= factorUpperBound):
# test if n is evenly divisible by factor
       if (n % factor == 0):
isPrime = False
           break

       factor = factor + 1

   # Output
   if isPrime:
print(n)

n = n + 1

今天,你学会了解决问题优化代码的思路了吗,今天你有什么收获吗?

推荐 1
本文由 曹金龙 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册