• 2. 辗转相除法


    1. 辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求最大公约数的一种方法。它的具体做法是:用较大数除以较小数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。

    步骤:

    两个数的最大公约数是指能同时整除它们的最大正整数。
    设两数为a、b(a≥b),求a和b最大公约数的步骤如下
    (1)用a除以b(a≥b),a / b = q...r1;
    (2)若r1 == 0,则gcd(a,b) = q;
    (3)若r1 != 0,则b / r1 = q..r2;
    (4)若r2 == 0,则gcd(a,b) = r1;
    (5)若r2 != 0, 则重复上述(3),(4)步骤;

    实际过程:

    (1) a / b = q1 ... r1
       a = q1 * b + r1 b = b
       if: r1 == 0 , gcd(a, b) = b

    (2) b / r1 = q2 ... r2
       b = q2 * r1 + r2 r1 = r1
       if: r2 == 0 , gcd(b, r1) = r1;
       a = q1*q2*r1 + r1 b = q2*r1
       gcd(a, b) = r1

    复杂度: 在O(log max(a,   b)) 以内

    代码:

     int gcd (int a, int b) {
         return !b ? a : gcd (b, a % b);
     }

    2.扩展欧几里德算法

      扩展欧几里德算法是用来在已知 a, b 求解一组 x, y ,使它们满足贝祖等式:

    ax + by = gcd(a, b)(解一定存在)。扩展欧几里德常用在求解模线性方程及方程组中。

    理解 x 和 y:

      已知了 ax + by = gcd(a, b) 一定是有解的 (数论相关定理可证)。

      1. 显然当 b = 0,gcd(a, b) = a。 此时 x = 1, y = 0;

      2. a > b > 0 时:

        设 a x1 + b y1 = gcd (a, b); 

         b x2 + (a mod b) y2 = gcd (b, a mod b);

                 根据欧几里德原理  gcd(a, b) = gcd(b, a mod b);

       则 a x1 + b y1 = b x2 + (a mod b) y2;

       即: a x1 + b y1 = b x2 + (a - [a / b] * b) y2 = a y2 + b x2 - [a/b] * b y2;

        (这里说明一下: a mod b = a - [a / b] * b       [a / b]  代表取整 )

       那么 a x1 + b y1 = a y2 + b (x2 - [a / b] * y2).

       结论: x1 = y2; y1 = x2 - [a / b] * y2.

       这样就找到了求解x1 , y1 的方法。

    代码:

    int extgcd (int a, int b, int& x, int& y) {
        
        int d = a;
        if (b != 0) {
            d = extgcd (b, a % b, y, x);
            y -= (a/ b) * x;
        }
        else {
            x = 1;
            y = 0;
        }
        return d;
    } 

    这里返回的d 就是gcd(a, b) 的值。

    关于解 x 和 y 的大小:

      事实上,如果 ab ≠ 0 , 可知道 |x| ≤ b 且 |y| ≤ a.

  • 相关阅读:
    利用python 掌握机器学习的过程
    SendMessage用法
    python函数形参中的*args和**kwargs
    python 用win32修改注册表,修改打开IE浏览器的配置
    python .py .pyc .pyw .pyo .pyd区别
    代码性能提升10倍(ForkJoin)
    雪花算法生成id
    配置虚拟机
    kafka多线程消费
    Redis存储对象序列化和反序列化
  • 原文地址:https://www.cnblogs.com/astonc/p/10656932.html
Copyright © 2020-2023  润新知