挑戰每日打卡python基礎題
come with me !今日練習:判斷一個自然數是否是素數(質數)
素數(質數)的定義:
一個大于1的自然數,如果除了1和它本身以外,沒有其他正因數,則稱為素數(或質數)。例如,2、3、5、7、11等是素數,而4、6、8、9等不是素數。
方案一:
def is_prime_fast(a):
if a <= 1:
return False
y = 2
while y * y <= a: # 相比較而言,while y <= a: 優化循環條件,檢查到sqrt(a)
if a % y == 0:
return False
y += 1
return True
優化:將 while y <= a ,優化成 while y * y <= a
數學證明
為了更嚴謹,我們可以用數學歸納法證明:
命題:對于任何整數a > 1,如果a不是質數,那么它有一個因數b滿足b <= sqrt(a)。
證明:
假設a不是質數,那么存在兩個整數b和c,b >= 2,c >= 2,使得a = b * c。
假設b > sqrt(a)且c > sqrt(a):
那么b * c > sqrt(a) * sqrt(a) = a。
但b * c = a,矛盾。
因此,至少有一個因數(b或c)滿足<= sqrt(a)。
性能比較
對于a = 1000000:
while y <= a :需要約100萬次循環。
while y * y <= a:最多需要約1000次循環。
其他應用
這種優化不僅用于質數檢查,還用于:
因數分解:尋找所有因數時,只需檢查到sqrt(a)。
完美平方檢查:判斷a是否為完全平方數,可以檢查int(sqrt(a)) ** 2 == a。
方案二升級版:
# 輸入一個自然數,判斷是否是質因數
def prime(a):
if a <= 1:
return False
if a == 2:
return False
if a % 2 == 0: # 除2以外,所有的偶數都有因子
return True
y = 3
while y**y <= a:
while a % y == 0:
return True
y += 2 #如果一個數能被最小的質因數 3,5,7整除,再進行循環
return False
a = int(input("請輸入一個自然數:"))
print(prime(a))
進一步,減少循環判斷
跳過偶數:除了2,所有偶數都不是素數,因此可以跳過對偶數的檢查;
此外,針對奇數,可以先判斷被最小的質因數 3,5,7整除,再進行循環。
即檢查步長設為2(即檢查3, 5, 7, ...)。