求解两个正整数的最大公约数(Greatest Common Devisor),可以采用循环进行遍历,不过效率很低。所以引入欧几里得算法(Euclid's algorithm)。

欧几里得算法基于GCD递归引理

可以直接写出递归程序:

int GCD(int a, int b)
{
    if(0 == b)
        return a;
    else
        return GCD(b, a % b);
}
  • 复杂度分析
    运行时间与递归调用的次数成正比。

时间复杂度\(O(lg b)\),最坏情况下计算次数\(N\le 5log_{10}b\)

证明:欧几里得算法

  • 扩展欧几里得算法
    可以计算出满足下式的三元组\((d,x,y)\)
    \[d = GCD(a, b) = ax + by\]
int Euclid_extend(int a, int b, int* x, int* y)
{
    if(0 == b)
    {
        *x = 1;
        *y = 0;
        return a;
    }
    else
    {
        int r = Euclid_extend(b,a%b,x,y);
        int temp = *x;
        *x = *y;
        *y = temp - (*y)*(a/b);
        return r;
    }
}

简单证明:
\(b=0\)是递归基,易得一组解\(x=1,y=0\);
\(b \neq0\)时:
首先递归求解:
\[d'=gcd(b,a\%b)=bx'+(a\%b)y' \ \ \ \ \ \ \ \ \ \ \ \ \ \ (1)\]
我们知道:
\[d=gcd(a,b)=d'=gcd(b,a\%b)\ \ \ \ \ \ \ \ \ \ \ \ \ (2)\]
\[a\%b=a-b*\biggl\lfloor a/b \biggr\rfloor\ \ \ \ \ \ \ \ \ \ \ (3)\]
将(2)(3)式带入(1):
\[d=bx'+(a-b\biggl\lfloor a/b \biggr\rfloor)y'=ay'+b(x'-\biggl\lfloor a/b \biggr\rfloor y')\]
所以,令\(x=y'\)\(y=x'-\biggl\lfloor a/b \biggr\rfloor y'\),就可以满足\(d=ax+by\)

12-20 08:40