質數定理:
1、從2開始到自身的-1的數中找到一個能整除的(從2開始到自身開平方的數中找到一個能整除的)。
2、一個合數一定可以分解成幾個質數的乘積,也就是說,一個數如果能被一個質數整除就是合數。(使用列表保存質數)
使用定理1的基本寫法:
(1)
n = 100 for i in range(2, n): for j in range(2, i): if i % j == 0: break else: print(i, end=' ')
這種基本寫法效率不高,有2點可以改進的地方:
1、第一層循環的i取值時,因為偶數確定不是質數,所以排除偶數,使用range()函數排除偶數,range(3, n, 2)這樣就減少了一半的數。
2、第二層循環j取值時,考慮從2開始到i開平方取值,同時也把偶數排除range(3, int(i**0.5)+1, 2)這樣也可減少一半的數。2就是質數,單獨打印。
(2)改進(1)
n = 100 print(2) for i in range(3, n, 2): for j in range(3, int(i**0.5)+1, 2): if i % j == 0: break else: print(i, end=' ')
(3)再(2)的基礎上還有優化的點,發現第一層循環i取值時,當i>10時,5的倍數也可排除
n = 100 print(2) for i in range(3, n, 2): if i > 10 and i % 5 == 0: continue for j in range(3, int(i**0.5)+1, 2): if i % j == 0: break else: print(i, end=' ')
(4)利用定理2,用列表保存上一次的運算結果
n = 100 L = [2] for i in range(3, n, 2): for j in L: if i % j == 0: break else: L.append(i) print(L)
此種寫法的效率不高,第一層循環的i沒必要與列表中的每一個元素取余,與從2開始到i的開平方處之間的數取余即可。
(5)改進(4)
n =100 L = [2] for i in range(3, n, 2): flag = False for j in L: if i % j == 0: flag = True break if j > int(i**0.5): break if not flag: L.append(i) print(L)
第二層循環第二個判斷處if j > int(i**0.5)
程序運行時,每次判斷i都會開平方,所以提到循環之外
(6)改進(5)
n = 100 L = [2] for i in range(3, n, 2): flag = False num = int(x**0.5) for j in L: if i % j == 0: flag = True break if j > num: break if not flag: L.append(i) print(L)
————————————————
版權聲明:本文為CSDN博主「夢兮嗣留影」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u013179337/article/details/81588980