扩展欧几里得算法
本文主要讲解如何直观地理解扩展欧几里得算法,并给出简要证明。
扩展欧几里得算法是给定一组整数a和b,求解出一组x和y,使得ax + by = gcd(a, b).
算法的第一步是先执行最大公约数的算法过程:
自然地,最后一次迭代的结果就是我们需要的等式右边:
因此对于最后一次迭代,令x = 1,y = 0,即可满足所需等式:
那么再反推到之前的迭代。对于每一次迭代,都有$a_{之后}=b_{之前}$,且 $b_{之后}=a_{之前}-[\frac{a_{之前}}{b_{之前}}]\cdot b_{之前}$ (注:[ ]是取整符号)。而为了让扩展欧几里得等式成立,需要使$a_{之前}*x_{之前}+b_{之前}*y_{之前}=a_{之后}*x_{之后}+b_{之后}*y_{之后}$成立
代换后得到:
$a_{之前}*x_{之前}+b_{之前}*y_{之前}=b_{之前}*x_{之后}+\left ( a_{之前}-[\frac{a_{之前}}{b_{之前}}]\cdot b_{之前} \right )*y_{之后}$
将等式的右边整理一下得到:
$a_{之前}*x_{之前}+b_{之前}*y_{之前}= a_{之前}*y_{之后}+b_{之前}*(x_{之后}-[\frac{a_{之前}}{b_{之前}}]*y_{之后})$
因此为了使这个等式成立,可得:
$\[\left\{\begin{matrix} x_{之前}=y_{之后} \\ y_{之前}=x_{之后}-[\frac{a_{之前}}{b_{之前}}]*y_{之后} \end{matrix}\right.\]$
再一直层层往前回推,直到a、b变为最原始的a、b,则得到的x和y就是所要求的值。
这个算法好像没有非递归的写法,只有递归的写法。算法如下(将往下推的步骤写在调用下一层递归之前,把往回推的过程写在调用下一层递归之后):
ext_gcd(a, b) returns [x, y] : if (b == 0) return [1, 0]; [x, y] = ext_gcd(b, a%b); temp = x; x = y; y = temp - a / b * y; return [x, y];