解決Python中迴文數和質數的問題
一、前言
今天學習視訊時課後作業是找出1000以內既是素數又是迴文數的數,寫程式碼這個很容易,結果一執行遇到了bug,輸出結果跟預期不一樣,除錯了快30min,再接著一通搜尋和回看視訊才發現問題所在。所以特地寫下來,方便以後檢視。問題的關鍵是判斷素數過程中for…else的用法上(具體看後面程式碼)
二、實現判斷素數的功能
質數(Prime number),又稱素數,指在大於1的自然數中,除了1和該數自身外,無法被其他自然數整除的數(也可定義為只有1與該數本身兩個因數的數)。via——Wikipedia
所以採用窮舉法只要在2~n-1的區間,沒有一個數能整除n,那麼n就是素數。
對2-n-1區間進行合理優化,假設x*y=n(x<=y),那麼當x和y相等時,x有最大值。即x=y=sqrt(n),所以x的區間就可以限制為2~sqrt(n)+1。還有疑問,可以在再多想想,紙上算一算。
因為這裡要用到sqrt()方法,所以需要匯入math模組。
不多說,直接上程式碼:
# 求解1000以內的所有素數,正確版本 import math num = 2 count = 0 list_s = [] max_d = 1000 while num < max_d: length = int(math.sqrt(num)+1) # 對遍歷範圍進行合理優化 for i in range(2,length): # 注意從2開始 if num % i == 0: break else: # 這裡的else跟for對齊,而不是跟if,表示只有for順利執行時,else才執行 count += 1 list_s.append(num) # 存入列表 num += 1 if count == 0: print(max_d,'以內沒有素數') else: print(max_d,'以內的素數有',count,'個,分別是:',list_s)
輸出結果:
這個程式碼完全沒有問題,然後下面給出一個有問題的程式碼:
# 求解40以內的所有素數,錯誤版本 import math num = 2 count = 0 list_s = [] max_d = 40 while num < max_d: length = int(math.sqrt(num)+1) # 對遍歷範圍進行合理優化 for i in range(2,length): # 注意從2開始 if num % i == 0: break else: # 這裡的else跟if對齊,會導致一個素數會被寫入int(math.sqrt(num))-1次,同時一些非素數也會被當做素數 count += 1 list_s.append(num) # 存入列表 num += 1 if count == 0: print(max_d,list_s)
輸出結果:
所以,一定要認真對待迴圈中else對齊問題。這個在解決素數問題中很重要。小結一下while…else和for…else
只有迴圈完所有次數,才會執行 else ,迴圈體中有continue存在,也不影響else執行。
一旦迴圈體中觸發了break ,就會阻止 else 語句塊的執行。
三、實現判斷迴文數的功能
迴文數即從左到右和從右到左一樣。如:12321。
方法:
把已知的num1數反過來,得到num2,如123變為321,採用//10 %10 *10等運算操作,其中還要藉助一個臨時變數tmp
判斷如果num1 == num 2,則num1是迴文數,反之不是
程式碼如下:
# 求解1000以內的所有迴文數 num = 0 # 這裡num從0開始 list_h = [] max_d = 10000 count = 0 while num < max_d: tmp = num num_p = 0 while tmp != 0: num_p = num_p*10 + tmp % 10 tmp //= 10 if num_p == num: list_h.append(num) count += 1 num += 1 if count == 0: print(max_d,'以內沒有迴文數') else: print(max_d,'以內的迴文數有',list_h)
更新:對於判斷迴文數或者回文字串,採用雙端佇列的資料結構,會非常簡單。實現如下:
from collections import deque def palindrome(word): dq = deque(word) while len(dq) > 1: if dq.pop() != dq.popleft(): return False return True if __name__ == '__main__': max_num = 10000 for i in range(max_num): s = str(i) if palindrome(s): print(i,end=',')
四、實現同時判斷迴文數和質數
需要選擇是否巢狀以及先判斷迴文還是先判斷素數,所以又四個版本。大家可以自己思考每個版本的效能上有無區別,佔用空間有無區別。因為我也沒有太想明白,所以沒有放上來。
我寫了四個版本,都能實現需求。不過從效能上,在我測試的100-1000000區間,採用巢狀的先求解迴文再判斷素數要快一些。
不多說,四個版本的程式碼全部在寫下面,可以自行刪掉相應的'''標記進行測試。
''' # 版本一、求1000以內的迴文素數,多層巢狀,先求素數後迴文數 import math num = 2 count = 0 list_s = [] list_sh = [] max_d = 1000 while num < max_d: length = int(math.sqrt(num)+1) for i in range(2,length): if num % i == 0: break else: list_s.append(num) tmp = num num_p = 0 while tmp != 0: num_p = num_p * 10 + tmp % 10 tmp //= 10 if num == num_p: list_sh.append(num) count +=1 num += 1 print(max_d,'以內的素數有:',list_s) if count == 0: print(max_d,'以內沒有既是素數又是迴文數的數') else: print(max_d,'以內既是素數又是迴文數的數有',list_sh) ''' ''' # 版本二、求1000以內的迴文素數,先求迴文數後求素數 import math num = 2 count = 0 list_h = [] list_hs = [] max_d = 1000 while num < max_d: tmp = num num_p = 0 while tmp != 0: num_p = num_p * 10 + tmp % 10 tmp //= 10 if num == num_p: list_h.append(num) length = int(math.sqrt(num)+1) for i in range(2,length): if num % i == 0: break else: list_hs.append(num) count +=1 num += 1 print(max_d,list_h) if count == 0: print(max_d,list_hs) ''' ''' # 版本三、求1000以內的迴文素數,先求素數再求迴文數 import math num = 2 list_s = [] max_d = 1000 while num < max_d: length = int(math.sqrt(num)+1) for i in range(2,length): if num % i == 0: break else: # 注意這裡的else是和for對齊 list_s.append(num) num += 1 count = 0 list_sh = [] for i in list_s: tmp = i num_p = 0 while tmp != 0: num_p = num_p*10 + tmp % 10 tmp //= 10 if num_p == i: list_sh.append(i) count += 1 print(max_d,list_sh) ''' ''' # 版本四、求1000以內的迴文素數,先求迴文數,再求素數 import math num = 2 list_h = [] max_d = 10000 while num < max_d: tmp = num num_p = 0 while tmp != 0: num_p = num_p*10 + tmp % 10 tmp //= 10 if num_p == num: list_h.append(num) num += 1 count = 0 list_sh = [] for hn in list_h: length = int(math.sqrt(hn)+1) for i in range(2,length): if hn % i == 0: break else: # 注意這裡的else是和for對齊 list_sh.append(hn) count += 1 print(max_d,'以內的迴文數有:',list_sh) '''
五、總結
這個過程幫助自己更加深刻的理解了if…elif…else 、for…else和while…else以後使用時會更加註意。
以上這篇解決Python中迴文數和質數的問題就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。