zoukankan      html  css  js  c++  java
  • ex08 欧几里德算法

    描述

    说明

    • 欧几里得算法又称辗转相除法,可用于求两个正整数的最大公约数

    示例

    • a = 30, b = 18,求 ab 的最大公约数
      1. a % b = 12 => a = 18, b = 12
      2. a % b = 6 => a = 12, b = 6
      3. a % b = 0 => 此时的 b 即为原来两数的最大公约数

    补充

    • a 不必大于 b,因为取模操作可以将大的数提前

    要求

    • 写出“欧几里德算法”的程序,起名为 gcd()
    • gcdGreatest Common Divisor 的缩写

    程序

    def gcd(num1, num2):
        while num2 != 0:
            num1, num2 = num2, num1 % num2
        return num1
    

    证明

    证法一

    num1, num2, m, r, d 均为自然数

    不妨设 num1 > num2d 为两个数的任意一个公约数 且 num1 / num2 = m ...... r

    => r = num1 - m * num2 => r/d = (num1 - m * num2)/d = num1/d - m*num2/d

    因为 dnum1, num2 的公约数,且 m 为自然数,所以 r/d 也是自然数

    => d 必是 r 的约数

    => 求 num1num2 的最大公约数,可以转为求 num2r 的最大公约数

    证法二

    step1 证明 d 是 r 的约数

    dnum1, num2 的最大公约数

    num1 的某一个约数 m1, num2 的某一个约数 m2,使得 num1 = m1 * d, num2 = m2 * d —— (1)

    不妨设 r = num1 % num2 = num1 - m * num2 —— (2)

    将 (1) 代入 (2),得 r = m1 * d - m * (m2 * d) = (m1 - m * m2) * d

    => dr 的约数

    step2 证明 m1-m*m2 与 m2 互质

    (m1 - m * m2)m2 不互质

    不妨设 (m1 - m * m2) = k1 * d', m2 = k2 * d', (d'>1)

    m1 = m * m2 + k1 * d' = m * (k2 * d') + k1 * d' = (m * k2 + k1) * d'

    => num1 = m1 * d = [(m * k2 + k1) * d'] * d = (m * k2 + k1) * (d' * d),
    num2 = m2 * d = (k2 * d') * d = k2 * (d' * d)

    => num1num2 有公约数 (d' * d)

    因为 d' > 1, d >= 1,所以 (d' * d) > d

    => 与开头题设矛盾

    => (m1 - m * m2)m2 互质

    => d 也是 rnum2 的最大公约数

  • 相关阅读:
    js 运算符优先级
    原生js获取样式
    RGBA 与opacity
    闭包(自己的学习+理解~~水水的)
    css 单位-px、em、rem、百分比
    js之正则1
    querySelector和querySelectorAll
    关于瀑布流的算法(转淘宝ued)
    瀑布流的几个注意点
    jsonp跨域
  • 原文地址:https://www.cnblogs.com/yorkyu/p/10367428.html
Copyright © 2011-2022 走看看