java - 欧几里得算法是如何工作的?

标签 java algorithm greatest-common-divisor

我刚刚在我的讲义中发现了这个计算最大公约数的算法:

public static int gcd( int a, int b ) {
    while (b != 0) {
        final int r = a % b;
        a = b;
        b = r;
    }
    return a;
}

所以r就是b除以a的余数(取模)。然后将b赋给a,余数赋给b,返回a。我这辈子都看不懂这是怎么回事!

然后,显然这个算法不适用于所有情况,然后必须使用这个算法:

public static int gcd( int a, int b ) {
    final int gcd;
    if (b != 0) {
        final int q = a / b;
        final int r = a % b; // a == r + q * b AND r == a - q * b.
        gcd = gcd( b, r );
    } else {
        gcd = a;
    }
    return gcd;
}

我不明白这背后的原因。我通常会递归并且擅长 Java,但这让我望而却步。请帮忙?

最佳答案

Wikipedia article 包含一个解释,但不容易立即找到它(而且,过程 + 证明并不总是回答“为什么它有效”的问题)。

基本上可以归结为这样一个事实,即对于两个整数 a、b(假设 a >= b),总是可以写出 a = bq + r,其中 r < b。

如果 d=gcd(a,b) 那么我们可以写 a=ds 和 b=dt。所以我们有 ds = qdt + r。因为左边可以被 d 整除,所以右边也必须可以被 d 整除。并且由于 qdt 可以被 d 整除,因此结论是 r 也必须被 d 整除。

总结一下:我们有 a = bq + r,其中 r < b 并且 a、b 和 r 都可以被 gcd(a,b) 整除。

因为a >= b > r,我们有两种情况:

  1. 如果 r = 0 则 a = bq,因此 b 除 b 和 a。因此 gcd(a,b)=b。
  2. 否则 (r > 0),我们可以将求 gcd(a,b) 的问题简化为求 gcd(b,r) 完全相同的数(因为 a、b 和 r 都是可整除的)通过 d).

为什么会减少?因为 r < b。所以我们正在处理肯定更小的数字。这意味着在我们达到 r = 0 之前,我们只需要应用这种减少有限次数。

现在,r = a % b 这有望解释您的代码。

关于java - 欧几里得算法是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6005582/

相关文章:

algorithm - 如果一个词由两个有效词组成

algorithm - 服装识别算法

java - 查找具有子路径且具有最大gcd(起始节点,结束节点)的路径

c - 找到最小公倍数

java - java加载图片函数的速度

java - 将来自多个输入的数据保存到文件

java - 在 junit 测试期间无法加载 ResourceBundle

java - 如何将 Power BI 嵌入到基于 Spring 的项目中?

java - A* 算法无法正常工作

c++ - 尝试将 C 代码转换为 C++ - 交互式二进制欧几里得算法