zoukankan      html  css  js  c++  java
  • 欧几里得算法(代码及证明过程)

    欧几里得算法(代码及证明过程)

    一、基础知识

    欧几里得算法的原理是 GCD递归定理

    GCD递归定理:

    对任意 非负整数 a 和 任意 整数 bgcd(a,b) = gcd(b, a mod b)

    为了证明这个定理,我们首先需要知道一下几个有关 gcd基本知识相关等式跟推论

    1.1 基本知识:

    1. 公约数

      定义:如果 d|a(d 整除 a)且 d|b,那么 d 是 a 与 b 的 公约数

      性质:如果 d|ad|b,那么 d|(ax + by); x,y ∈ Z(任意整数)

    2. 最大公约数

      定义:两个非零整数 a 和 b 的公约数里最大的就是 最大公约数

    1.2 相关等式跟推论:

    1. 等式 1:如果 a|b 且 b|a 那么 a = ±b
    2. 等式 2:如果 d|a 且 d|b 那么 d|(ax + by); x,y ∈ Z
    3. 等式 3: a mod n = a - n⌊a/n⌋(向下整除); a∈Z,n∈N*(正整数)
    4. 推论 1:对任意整数 a , b,如果 d|a 且 d|bd|gcd(a, b)

    二、证明过程

    如果我们想要获得结论gcd(a,b) = gcd(b, a mod b)

    那么我们只需要证明gcd(a,b)|gcd(b, a mod b) 且 gcd(b,a mod b)|gcd(a,b)就可以利用等式 1来证明他俩相等了。

    2.1 证明 gcd(a,b)|gcd(b,a mod b)

    d = gcd(a, b)

    d|a 且 d|b

    ∵ 由 等式 3 可知:(a mod b) = a - qb q = ⌊a/b⌋

    a mod b 是 a 与 b 的线性组合

    ∴ 由 等式 2 可知 :d|(a mod b)

    d|b 且 d|(a mod b)

    ∴ 由 推论 1 可知 d|gcd(b, a mod b)

    等价结论: gcd(a, b)|gcd(b, a mod b)

    2.2 证明 gcd(b,a mod b)|gcd(a,b)

    c = gcd(b, a mod b)

    c|b 且 c|(a mod b)

    a = qb + r

    r = a mod b

    q = ⌊a/b⌋

    ∴ a 是 b 和 (a mod b) 的线性组合

    ∴ 由 等式 2 可知:c|a

    c|a 且 c|b

    ∴ 由 推论 1 可知:c|gcd(a, b)

    等价结论: gcd(b, a mod b)|gcd(a, b)s

    2.3 证明 gcd(a,b) = gcd(b, a mod b)

    由 上述两个结论 可知:

    gcd(a, b)|gcd(b, a mod b)

    gcd(b, a mod b)|gcd(a, b)

    ∴ 由 等式 1 可知:

    gcd(a, b) = gcd(b, a mod b)

    到这里 GCD递归定理 就证明结束了

    三、代码

    在这里我放上几个常用的获取 两个数字GCD的代码:

    1. 递归:

      // 一般形式
      int gcd(int a, int b) {
          if(b == 0)
              return a;
          return gcd(b, a % b);
      }
      
      // 简化形式
      int gcd(int a, int b) {
          return (b==0) ? a : gcd(b, a % b);
      }
      
    2. 非递归:

      int gcd(int a, int b) {
          int tmp;
          while(b != 0) {
              tmp = b;
              b = a % b;
              a = tmp;
          }
          return a;
      }
      
    3. 位运算:

      // 一般形式
      int gcd(int a, int b) {
          while(b) {
              a %= b;
              // 下面三行是交换 a 跟 b 的值
              b ^= a;
              a ^= b;
              b ^= a;
          }
          return a;
      }
      
      // 简化版
      int gcd(int a,int b) {
          while(b^=a^=b^=a%=b);
          return a;
      }
      

    四、参考资料

    《算法导论 (第三版)》 -- 第31章 数论算法

    GCD算法_Niteip's blog-CSDN博客_gcd 算法

  • 相关阅读:
    linux配置虚拟主机
    mysql允许远程登录
    php优化
    php socket 函数
    1-- prometheus安装、图形化界面
    Ansible Roles
    Ansible 的 Playbook
    Ansible 变量
    Ansible 模块
    Ansible入门;Ansible ad-hoc; ansible-vault加密工具 ;ansible-console
  • 原文地址:https://www.cnblogs.com/F4lc0n/p/14318086.html
Copyright © 2011-2022 走看看