我們學習了python的迴圈語句和if分支結構後,就可以做很多是事情了:比如經典的求素數問題。
定義:乙個大於1的自然數,只能被1和它自身整除的數。
根據定義要想判定乙個大於1的數是不是素數,要整除從2開始到它自身截止在內的所有數根據能不能被整除來判斷。
比如求100以內的素數只根據定義我們可以寫成:
#計數for i in range(2,100):
for j in range(2,i):
if i % j == 0:
break
else:
count += 1
print(count)
但是這樣的效率高效嗎?我們求一下10000以內的素數看一下能用多久時間。首先呼叫一下求時間的函式:import datetime。
#計數time = 0
# 計時間
start = datetime.datetime.now()
for i in range(2,10000):
for j in range(2,i):
if i % j == 0:
break
else:
count += 1
time = (datetime.datetime.now() - start).total_seconds()
print(count)
print(time)
1229
0.749043
我們可以看到相對於計算機而言時間還是很長的。那麼怎麼在結構不變的情況下優化呢?其實完全可以從定義再入手,乙個偶數肯定不是素數因此判定乙個範圍內的素數我們完全可以先把偶數去除。
print(2)
for i in range(3,10000,2):
這樣很明白迴圈次數減少了近一半,節省了很多時間。但是只優化這點肯定是不夠的,我們知道除了素數外,其它的數必定是兩個數的乘積,並且這兩個數乙個大於等於該數的開平方,另乙個小於等於該數的平方根。只要找到其中的乙個另乙個就不用除了,因此我們除到這個數的開平方根就行了。所以可以寫成如下:
print(2)
for i in
range(3,10000,2):
for j in
range(3,int(i**0.5)+1):
然後還有乙個優化點:既然我們已經知道了是在奇數群裡找素數,那麼也就可以不用除以偶數了,畢竟奇數除以偶數怎麼也除不盡。當我們把這些優化點都加上去看一下所需的時間。
#計數,把數字2也算上
time = 0
# 計時間
start = datetime.datetime.now()
for i in range(3,10000,2): #利用步長剔除偶數
for j in range(3,int(i**0.5)+1,2): #只除到平方根即可
if i % j == 0:
break
else:
count += 1
time = (datetime.datetime.now() - start).total_seconds()
print(count)
print(time)
1229
0.012
我們可以看到時間縮減了很多,效率大大提公升!
求質數表 素數篩求素數 效率比較 數論相關
求質數表 素數篩求素數 效率比較 數論相關 第乙個是平時最常用的基本寫法 還有一種寫法是for j i 2 j第二個是以i i為起點開始篩的,要注意浮點溢位!第三個不太好簡潔地說清楚,詳細 程式中途分別輸出每次計算了的prime 500000 從而為了驗證計算結果的正確性的 include incl...
遞迴 高效率求2的n次冪
思路 使用翻一番的技巧。比如,2的9次 則 1 2 2 2 2 4 4 4 16 16 16 指數 1 2 4 8 能翻倍的情況下 能翻 while ex 1 不能翻倍的情況下 不能翻 則把差值作為指數遞迴計算。當差值為0時,就說明到頭了,只剩最後乙個數字。return 1 乘數字本身即可。retu...
關於在指定區間求第k小的數,求高效率演算法
一 問題 給定乙個整數數列a 1.n 其中每個元素都不相同,你的程式要能回答一組格式為q i j k 的查詢,q i,j k 的意思是 在a i.j 中第k小的數是多少?例如令 a 查詢格式為q 2 5 3 數列段a 2.5 第3小的數是5,所以答案是5。第一行包括乙個正整數n,代表數列的總長度,還...