欧几里得算法
假设有两个非负整数a,ba,ba,b,并且a,ba,ba,b都不等于0,那么a,ba,ba,b的最大公约数等于其中较小的数和a,ba,ba,b相除的余数的最大公约数。
用公式表达为gcd(a,b)=gcd(b,a(modb))gcd(a,b)=gcd(b,a\pmod{b})gcd(a,b)=gcd(b,a(modb)),其中a>=ba>=ba>=b。
证明过程
假设k可以同时整除a,b。∵a>=b∴a=kb+r∴k也可以整除r。∴gcd(a,b)=gcd(b,a(modb))成立。 \begin{aligned} 假设 k 可以同时整除a,b。\\ &\because a>=b \\ &\therefore a=kb+r \\ &\therefore k \quad 也可以整除\quad r 。\\ &\therefore gcd(a,b)=gcd(b,a\pmod{b}) \quad 成立。 \end{aligned} 假设k可以同时整除a,b。∵a>=b∴a=kb+r∴k也可以整除r。∴gcd(a,b)=gcd(b,a(modb))成立。
代码实现
def gcd_by_euclidean_algorithm(a: int, b: int) -> int:
while b != 0:
a, b = b, a % b
return a
# expect 1
print(gcd_by_euclidean_algorithm(3, 4))
# expect 4
print(gcd_by_euclidean_algorithm(12, 4))
# expect 6
print(gcd_by_euclidean_algorithm(18, 24))
扩展欧几里得算法
已知正整数a,ba,ba,b,求解一组x,yx,yx,y,使它们满足贝祖等式ax+by=gcd(a,b)ax+by=gcd(a,b)ax+by=gcd(a,b)。
特别的,当a⊥ba\perp ba⊥b时,求解的xxx为aaa模bbb的逆元,即ax≡1(modb)ax\equiv 1\pmod{b}ax≡1(modb)。
扩展欧几里得算法的代码实现
扩展欧几里得算法实质上是求解贝祖等式的解。
def extended_gcd(a: int, b: int) -> int:
# 当a为0时,贝祖等式的系数x=0,y=1,最大公约数为b
if a == 0:
return b, 0, 1
# 递归求取最大公约数和贝祖系数
d, x, y = extended_gcd(b % a, a)
# 更新系数
return d, y - (b // a) * x, x
根据扩展欧几里得算法求解模逆元
代码实现如下:
def mod_inverse(a, m):
gcd, x, y = extended_gcd(a, m)
# 当a,b不互质时,不存在模逆元
if gcd != 1:
raise Exception("Not found mod inverse.")
return x % m
注意: 调用扩展欧几里得算法求得xxx可能是负数,这时需要对xxx模mmm,确保xxx是一个正数。
求证扩展欧几里得算法中系数公式
扩展欧几里得算法的核心是更新贝祖等式系数的公式,这些公式是基于欧几里得算法的递归性质推导出来的。下面是详细的证明过程:
初始等式:ax+by=gcd(a,b)ax+by=gcd(a,b)ax+by=gcd(a,b),其中x,yx,yx,y是贝祖系数。
递归的第二层存在等式:b(moda)∗x1+a∗y1=gcd(b(moda),a)b\pmod{a} * x_1+a*y_1=gcd(b\pmod{a},a)b(moda)∗x1+a∗y1=gcd(b(moda),a)。
根据欧几里得算法可知:gcd(a,b)=gcd(b(moda),a)=dgcd(a,b)=gcd(b\pmod{a},a)=dgcd(a,b)=gcd(b(moda),a)=d,其中ddd表示a,ba,ba,b的最大公约数。
又因为:b(moda)=b−⌊ba⌋∗ab \pmod{a} = b - \lfloor \frac{b}{a} \rfloor * a b(moda)=b−⌊ab⌋∗a
将此式子带入第二层的递归的等式中可得:
(b−⌊ba⌋∗a)∗x1+a∗y1=da∗(y1−⌊ba⌋∗x1)+b∗x1=d (b-\lfloor \frac{b}{a} \rfloor *a)*x_1+a*y_1=d \\ a*(y_1-\lfloor \frac{b}{a} \rfloor *x_1) + b*x_1 = d (b−⌊ab⌋∗a)∗x1+a∗y1=da∗(y1−⌊ab⌋∗x1)+b∗x1=d
因此递归时,两次递归之间的系数关系为:
x=y1−⌊ba⌋∗x1y=x1 \begin{aligned} x&=y_1-\lfloor \frac{b}{a} \rfloor *x_1 \\ y&=x_1 \end{aligned} xy=y1−⌊ab⌋∗x1=x1
4057

被折叠的 条评论
为什么被折叠?



