zoukankan      html  css  js  c++  java
  • [知识点] 6.4.2 欧几里得算法与扩欧算法

    总目录 > 6 数学 > 6.4 数论 > 6.4.2 欧几里得算法与扩欧算法

    前言

    没什么好说的啦。

    更新日志

    Update - 20200728

    重整了一下章节之间的逻辑,以及标题进行了替换。

    子目录列表

    1、欧几里得算法

    2、扩欧算法

    3、求解

    4、应用

    6.4.2 欧几里得算法与扩欧算法

    1、欧几里得算法

    欧几里得算法(Euclidean Algorithm),又称为辗转相除法,用于计算两个正整数 x, y 的最大公约数,公式为:

    gcd(x, y) = gcd(y, x mod y)

    代码:

    1 int gcd(int x, int y) {
    2     return y ? gcd(y, x % y) : x; 
    3 }

    同时,你也可以选择使用 algorithm 库中的 __gcd(x, y) 函数。

    2、扩欧算法

    扩展欧几里得算法(Extended Euclidean algorithm)是欧几里得算法的扩展版本,简称扩欧算法。已知正整数 a, b,求得最大公约数的同时可以求得 x, y(其中一个很可能为负数),使它们满足裴蜀定理

    ax + by = gcd(a, b)

    3、扩欧求解

    求解方法和欧几里得算法类似,在辗转相除的基础上增加两个数组,具体步骤见下:

    i = 5时,s[i] = -9, t[i] = 47,分别为裴蜀定理中的 x 和 y;余数r[i]为最大公约数。

    i = 6时,s[i] = 23, t[i] = -120,用于验证正确性,验证方法:t[i] * (-2) = 240, s[i] * 2 = 46,分别为 a 和 b。 

    代码 1:

    1 int exgcd(int a, int b) {
    2     if (!b) return ob;
    3     x = oox - a / b * ox, oox = ox, ox = x;
    4     y = ooy - a / b * oy, ooy = oy, oy = y;
    5     return exgcd(ob = b, a % b);
    6 }

    (最终的 x 存放在 oox 中,y 同理)

    这是根据算法的描述自己写的代码,在参考了更多 wiki 和博客的介绍后,发现 x 和 y 并不需要弄这么多变量来存,而可以先求得最大公约数后反推 x 和 y。

    代码 2:

    1 int exgcd(int a, int b, int &x, int &y) {
    2     if (!b) {
    3         x = 1, y = 0;
    4         return a;
    5     }
    6     int res = exgcd(b, a % b, x, y);
    7     ox = x, x = y, y = ox - a / b * y;
    8     return res;
    9 }

    4、扩欧应用

    ① 求线性同余方程

    线性同余方程形如  的方程。

    由于方程和 ax + by = c 是等价的,根据扩展欧几里得定理,存在整数解等价于 gcd(a, b) 整除 c(gcd(a, b) | c)。

    所以,根据上述求解方法求得 x 和 y 后,方程两边同时除以 gcd(a, b) 且乘 c,即 cx / gcd(a, b)和cy / gcd(a, b) 为方程的一组解。                

    (gcd(a, b) = 1,且 x0, y0 为其中一组解时,所有解可以表示为 x = x0 + bt, y = y0 - at,t 为任意整数)

    代码略。

    ② 求乘法逆元

    乘法逆元全称为模意义下的乘法运算的逆元(Modular Multiplicative Inverse),如果一个线性同余方程满足:

    则 x 称为 a mod b 的逆元,记作a ^ -1。

    作为线性同余方程的一种特殊情况,思路是类似的:方程和 ax + by = 1 是等价的,存在整数解等价于 gcd(a, b) 整除 1,即 gcd(a, b) = 1,即 a 和 b 互素

    代码略。

    乘法逆元同样可以用费马小定理来求,请参见:6.4.3 费马小定理

  • 相关阅读:
    Eclipse 导入项目乱码问题(中文乱码)
    sql中视图视图的作用
    Java基础-super关键字与this关键字
    Android LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot)的参数理解
    Android View和ViewGroup
    工厂方法模式(java 设计模式)
    设计模式(java) 单例模式 单例类
    eclipse乱码解决方法
    No resource found that matches the given name 'Theme.AppCompat.Light 的完美解决方案
    【转】使用 Eclipse 调试 Java 程序的 10 个技巧
  • 原文地址:https://www.cnblogs.com/jinkun113/p/12525731.html
Copyright © 2011-2022 走看看