编程语言
首页 > 编程语言> > 欧几里得算法及其扩展算法——数论

欧几里得算法及其扩展算法——数论

作者:互联网

欧几里得算法(gcd):

  又名辗转相除法,是求最大公约数的算法。辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数的差的最大公约数。两个数的最大公约数通常写成 gcd(a, b)
例如,计算a = 1071和b = 462的最大公约数的过程如下:
  从1071中不断减去462直到小于462(可以减2次,即商q0 = 2),余数是147: 1071 = 2 × 462 + 147. 然后从462中不断减去147直到小于147(可以减3次,即q1 = 3),余数是21: 462 = 3 × 147 + 21. 再从147中不断减去21直到小于21(可以减7次,即q2 = 7),没有余数: 147 = 7 × 21 + 0. 此时,余数是0,所以1071和462的最大公约数是21。
由此可以得到算法

递归:
int gcd (int n, int m)
{
        if (m == 0)
           return n;
        else
           return gcd(m, n % m);
}
迭代:
int gcd(int m,int n)
{
        int t = 1;
        while(t != 0) {
            t = m % n;
            m = n;
            n = t;
        }
        return m;
}

扩展的欧几里得算法(exgcd):

  是欧几里得算法(又叫辗转相除法)的扩展。已知整数a、b,扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足贝祖等式 ax+by=gcd(a,b)
例子过程展示
用类似辗转相除法,求二元一次不定方程47x + 30y = 1的整数解。

然后,把它们改写成“余数等于”的形式。

然后,倒着计算并带入式子 1, 2, 3:

得解 x = -7,y = 11

代码实现:
int exgcd(int a, int b, int &x, int &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int r = exgcd(b, a % b, x, y);
    int t = x;
    x = y;
    y = t - a / b * y;

    return r;
}

标签:147,13,17,数论,欧几里得,30,462,int,算法
来源: https://blog.csdn.net/weixin_43207025/article/details/90610931