python如何求解兩數(shù)的最大公約數(shù)
題目:
給定兩個自然數(shù),求這兩個數(shù)的最大公約數(shù)。
分析:
單看題目的話,非常簡單,我們可以循環(huán)遍歷自然數(shù),如果能夠整除兩個自然數(shù),就把這個數(shù)記下來,在這些記錄中找到最大的一個。
但是這樣做有幾個缺點:一是做除法計算量比較大,二是遍歷所有自然數(shù)完全沒有必要。另外,如果能夠循環(huán),還是不要遞歸,因為Python的函數(shù)遞歸最大棧空間是1000(如果我沒有記錯的話),如果數(shù)字大一些,很容易出現(xiàn)爆棧。
所以在這里有兩種處理方法:
1、如果較大的自然數(shù)除較小的一個自然數(shù),取得余數(shù),較小的自然數(shù)和余數(shù)的最大公約數(shù)就是我們要求的值。
2、如果較大的自然數(shù)減去較小的自然數(shù),取得差值,較小的自然數(shù)和差值的最大公約數(shù)就是我們要求的值。
基于以上兩條,我們就可以在根據(jù)定義得到的算法的基礎(chǔ)上進行改進,但是!減法操作當(dāng)然比取余要方便很多。而且在計算機里,做位運算的速度要比加減乘除都快,所以,我寫了四個算法,具體描述在代碼的 __doc__里有注釋闡述
代碼:
def greatest_common_divisor_1(self, num1, num2):
'''
數(shù)值計算尋找最大公約數(shù),給定兩個整數(shù),計算其最大公約數(shù),時間復(fù)雜度為 o(min(num1,num2)),取余運算復(fù)雜度高
'''
gbc = 1
for i in xrange(2, min(num1, num2)+1):
if num2 % i == 0 and num1 % i == 0:
gbc = i
return gbc
def greatest_common_divisor_2(self, num1, num2):
'''
輾轉(zhuǎn)相減法,時間復(fù)雜度最差為 o(min(num1,num2)),一般情況下都比這個要好。相減運算要比除法方便很多
'''
while num1 != num2:
if num1 > num2:
num1 = num1 - num2
else:
num2 = num2 - num1
return num1
def greatest_common_divisor_3(self, num1, num2):
'''
求余數(shù)法,取模運算比較麻煩,時間復(fù)雜度低 o(log max(num1, num2))
'''
while num1 != num2:
if num1 > num2:
if num1 % num2 == 0:
return num2
num1 = num1 % num2
else:
if num2 % num1 == 0:
return num1
num2 = num2 % num1
return num1
def greatest_common_divisor(self, num1, num2):
'''
求兩個數(shù)的最大公約數(shù)
綜合取余法和輾轉(zhuǎn)相減法,既能得到較好的時間復(fù)雜度,又能避免取余運算,時間復(fù)雜度穩(wěn)定 o(log max(num1,num2))
如果取兩個非常大的數(shù)的話,前面的方法很容易爆棧、取余困難等等,但是該方法沒有問題
a = 999999342353200
b = 777774234
print greatest_common_divisor(a, b)
'''
factor = 1
if num1 < num2:
return greatest_common_divisor_1(num2, num1)
while num1 != num2:
if num1 & 1 is False and num2 & 1 is False: # 均為偶數(shù)
num1 = num1 >> 1
num2 = num2 >> 2
factor *= 2
elif num1 & 1 is False and num2 & 1 is True:
num1 = num1 >> 1
elif num1 & 1 is True and num2 & 1 is False:
num2 = num2 >> 1
else:
if num1 > num2:
num1 = num1 - num2
else:
num2 = num2 - num1
return factor*num1
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Pandas數(shù)據(jù)集的合并與連接merge()方法
Pandas數(shù)據(jù)集的合并與連接(merge())是數(shù)據(jù)處理過程中常用的操作之一,在使用Pandas進行數(shù)據(jù)集合并時,可以使用merge()函數(shù)將兩個或多個數(shù)據(jù)集按照指定的列進行合并,本文就來介紹一下,感興趣的可以了解一下2023-11-11
使用python把json文件轉(zhuǎn)換為csv文件
這篇文章主要介紹了使用python把json文件轉(zhuǎn)換為csv文件,幫助大家更好的利用python處理數(shù)據(jù),感興趣的朋友可以了解下2021-03-03
使用Python中Tkinter模塊的Treeview?組件顯示ini文件操作
這篇文章主要介紹了使用Python中Tkinter模塊的Treeview組件顯示ini文件操作,Treeview組件位于ttk模塊,該模塊自Tk8.5開始引入,主題詳細介紹,需要的朋友可以參考一下2022-09-09
輕松掌握python的dataclass讓你的代碼更簡潔優(yōu)雅
本文總結(jié)了幾個我在使用Python的dataclass時常用的技巧,dataclass裝飾器可以幫助我們簡化數(shù)據(jù)類的定義過程,包括設(shè)置默認值、隱藏敏感信息、設(shè)置只讀對象以及將其轉(zhuǎn)化為元組和字典,通過使用dataclass,我們可以更高效地進行數(shù)據(jù)分析和處理,感興趣的朋友跟隨小編一起看看吧2025-01-01
利用Python+Opencv實現(xiàn)車牌自動識別完整代碼
這篇文章主要介紹了如何使用Python和OpenCV進行車牌識別,包括圖像預(yù)處理、車牌定位、分割和模板匹配等步驟,通過實戰(zhàn)項目,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2025-04-04
使用wxPython實現(xiàn)逐行加載HTML內(nèi)容并實時顯示效果
這篇博客中,我們將詳細分析如何使用 wxPython 構(gòu)建一個簡單的桌面應(yīng)用程序,用于逐行加載并顯示 HTML 文件的內(nèi)容,并在加載完成后通過瀏覽器組件呈現(xiàn)最終頁面,通過該應(yīng)用,我們可以體驗到逐行加載 HTML 內(nèi)容的視覺效果,類似于模擬代碼輸入,需要的朋友可以參考下2024-11-11
Python調(diào)用C語言動態(tài)庫的方法小結(jié)
這篇文章主要為大家詳細介紹了Python調(diào)用C語言動態(tài)庫的相關(guān)知識,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考一下2024-12-12

