本文节选自《50个与数学有关的Python编程》。创作结束,最后一篇献上源码。欢迎点赞、关注、收藏。

素数问题python函数(素数这个问题可不简单)(1)

创作计划

为什么创作?

不少老师教编程,喜欢拿教大学那一套来教中学生。笔者认为这是不合适的,中学生有中学的学习方法。我认为从数学入手才能让中学生更容易更快地融入编程。

往期回顾

01 余数

02 约数与倍数

正文

素数的定义是:除1外所有的正整数,如果仅仅能被自身和1整除,那么称为素数;

与素数对应的是合数:除1外所有的正整数,不是素数就是合数。

题1 判断N是不是素数

N = eval(input("请输入一个大于1的正整数:")) for i in range(2,N): if N % i == 0: print(f"{N}是合数") exit() # 用exit函数,不能用break。 print(f"{N}是素数")

这是根据定义来判断的,但这不是一个最好的办法。

题2 埃氏算法

埃氏指的是埃拉特色尼。埃拉特色尼是古希腊时代的地理学家和数学家,是人类历史上第一个正确测量地球半径的人。

这个算法的精髓在于,判断N是否为素数,不用判断N能否被N-1整除。实际上,过了N的一半,N就没法整除了。如能把10整除(除自身外)的最大的数是5。所以,上述算法,完全可以省下一半的循环,但这还不是最省的。

令a×a≥n,如果n能整除2~a中间的某个整数的话,其商一定在a~n之间;如果n整除a~n之间的某个整数的话,其商一定在2~a之间。所以判断n是否为素数的最省的方法是,看它能否被2~根号n的数整除。

如数字11,它的开方小于4,它不能被2,3整除,因此必为素数。

N = eval(input("请输入一个大于1的正整数:")) sqrt_N = int(pow(N,0.5)) #int能取出整数部分,如int(1.5)=1。 #int(x),如果x>0,则int相当于向下取整, #如果x<0,则int相当于向上取整 for i in range(2,sqrt_N 1): if N % i == 0: print(f"{N}是合数") exit() # 用exit函数,不能用break。 print(f"{N}是素数")

题3 找出100以内的孪生素数

形如(3,5)(5,7)(11,13)的一对素数叫孪生素数。

def is_prime(n): sqrt_n = int(pow(n,0.5)) for i in range(2,sqrt_n 1): if n % i == 0: return False #return让函数直接exit了 return True prime_list = [] for num in range(2,100): if is_prime(num) and is_prime(num 2): #注意and的执行顺序,只要当前一个是True时才会执行后一个 prime_list.append((num,num 2)) print(prime_list)

题4 素数列表

为什么在此提素数列表呢?因为这个是很多精彩常考的题。如找出2019以内所有的素数。

我们用埃氏算法:

  1. 建立2~N的数字列表
  2. 从小到大,如果一个数字能被前面的数字整除,就把它删了。
  3. 当执行到N的开方时,剩下的就是素数了。

如找出10以内的素数。

  1. 建立数字列表[2,3,4,5,6,7,8,9,10]
  2. 从2开始,凡是能被2整除(除2外)的就删了,剩下:[2,3,5,7,9]
  3. 再删除3的倍数,剩下:[2,3,5,7]
  4. 由于10的开方小于4,所以剩下的列表就是素数列表了。

这个算法适合人计算,对于计算机而言还要谨慎一点,关键点就在于,一个元素被删了之后,列表的下标要向前移动的。所以正确的做法是,从后往前删。

n = 2019 prime_list = list(range(2,n 1)) #建立列表 sqrt_n = int(pow(n, 0.5)) for i in range(2, sqrt_n 1): length = len(prime_list) for j in range(length-1,-1,-1): # 遍历删除列表,要从后往前遍历,否则会导致越界 if (prime_list[j] % i == 0) and (prime_list[j] != i): prime_list.pop(j) print(prime_list)

素数问题python函数(素数这个问题可不简单)(2)

,