約數:若是整數a能被整數b整除,那麼a叫作b的倍數,b叫作a的約數。python
最大公約數(Greatest Common Divisor,GCD):給定兩個整數a,b,兩個數的全部公共約數中的最大值即爲最大公約數。例如,12與16的最大公約數是4.算法
歐幾里得:展轉相除法(歐幾里得算法)函數
《九章算術》:更相減損術優化
gcd(a, b) = gcd(b, a mod b),意思是說a,b的最大公約數等於a/b的餘數(a%b)和b的最大公約數。spa
例如:gcd(60, 21) = gcd(21, 18) = gcd(18, 3) = gcd(3, 0) = 3 ;b=0是終止條件,此時的a就是最大公約數對象
證實:blog
def gcd(a, b): """最大公約數:僞遞歸(編譯器會進行優化)的效率與循環是同樣的""" if b == 0: # 當b=0是,a就是要獲得的最大公約數 return a else: return gcd(b, a % b) # 取到餘數 print(gcd(16, 12)) # 4 def gcd2(a, b): """非遞歸方法""" while b > 0: r = a % b a = b b = r return a # 此時b=0,達到循環終止條件 print(gcd2(12, 16)) # 4
a,b輸入的數字大小順序不一樣是否會影響計算結果?遞歸
print(gcd2(12, 16)) # 4 """ 12 16 r=12 a=16 b=12 r=4 a=12 b=4 r=0 a=4 b=0 因而可知a,b的順序不影響結果 """
利用歐幾里得算法實現一個分數類,支持分數的四則運算。編譯器
class Fraction: def __init__(self, a, b): """ 分數類——構造函數 :param a:分子 :param b:分母 """ self.a = a self.b = b x = self.gcd(a, b) # a,b的最大公約數 self.a /= x # 約分 self.b /= x def gcd(self, a, b): """最大公約數——非遞歸方法""" while b > 0: r = a % b a = b b = r return a # 此時b=0,達到循環終止條件 def LCM(self, a, b): """最小公倍數""" x = self.gcd(a, b) return a * b / x def __add__(self, other): """ 分數加法 對象a和b相加時,python自動根據對象a的__add__魔法方法進行加法操做 :param other: :return: """ # 1/12 + 1/20 a = self.a b = self.b c = other.a d = other.b denominator = self.LCM(b, d) # b,d的最小公倍數,最後的分母 numerator = a * (denominator / b) + c * (denominator / d) # 最後的分子 return Fraction(numerator, denominator) def __sub__(self, other): """ 分數減法 :param other: :return: """ a = self.a b = self.b c = other.a d = other.b denominator = self.LCM(b, d) # 分母的最小公倍數 numerator = a * (denominator / b) - c * (denominator / d) return Fraction(numerator, denominator) def __mul__(self, other): """ 分數乘法 1/5 * 3/10 :param other: :return: """ a = self.a b = self.b c = other.a d = other.b denominator = b * d numerator = a * c return Fraction(numerator, denominator) def __truediv__(self, other): """ 分數除法 (1/3)/(1/2)=2/3 :param other: :return: """ a = self.a b = self.b c = other.a d = other.b denominator = self.LCM(b, c) # 分母和除數分子最小公倍數 numerator = a * (denominator / b) + d * (denominator / d) # 最後的分子 return Fraction(numerator, denominator) def __str__(self): return "%d/%d" % (self.a, self.b) f = Fraction(30, 15) print(f) # 2/1 a = Fraction(1, 3) b = Fraction(1, 4) print(a + b) # 7/12 print(a-b) # 1/12 print(a * b) # 1/12 print(a / b) # 4/3