菜单
×
   ❮   
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

欧几里得算法

欧几里得算法以古希腊数学家欧几里得的名字命名,是最古老的非平凡算法,记载于欧几里得于公元前 300 年撰写的著名著作《几何原本》中。

欧几里得算法

欧几里得算法用于查找两个数字 \(a\) 和 \(b\) 的最大公约数(gcd)。

最大公约数是能整除 \(a\) 和 \(b\) 而不留余数的最大数字。

使用除法查找最大公约数。

结果:

{{ msgDone }}

计算

该算法使用带余数的除法。它使用上一步的余数来设置下一步的计算。

工作原理

  1. 从两个初始数字 \(a\) 和 \(b\) 开始。
  2. 进行带余数的除法:\(a=q_0 \cdot b + r_0\)
  3. 使用上一次计算的余数(\(r_0\)) 和除数(\(b\)) 来设置下一次计算:\(b=q_1 \cdot r_0 + r_1\)
  4. 重复步骤 2 和 3,直到余数为 \(0\)。
  5. 计算出的倒数第二个余数就是最大公约数。

继续阅读,了解如何手动、通过编程执行欧几里得算法,以及理解该算法的工作原理和原因。


数学术语

以下是描述欧几里得算法时需要了解的词语,以便理解本页的解释。

除数 (Divisor): 一个数字,我们可以用它来整除另一个数字,而不留余数。我们说 3 是 6 的除数,因为 \(6/3=2\),没有余数(余数为 0)。

余数 (Remainder): 用一个数除以另一个数后剩下的部分。7 除以 3 等于 2,余数为 1。(所以 3 不是 7 的除数。)

公约数 (Common divisor): 对于数字 \(a\) 和 \(b\),公约数是可以整除 \(a\) 和 \(b\) 而不产生余数的数字。18 和 12 的公约数是 2、3 和 6,因为 18 和 12 都可以被 2、3 和 6 整除,而没有余数。

最大公约数 (Greatest common divisor): 公约数中最大的一个。18 和 12 的最大公约数是 6,因为它是公约数 2、3 和 6 中最大的一个。

最大公约数在数论领域以及用于加密信息的密码学中都有应用。

注意: 欧几里得算法使用的所有数字都是整数。


手动演练

为了理解欧几里得算法的工作原理,以及如何编写其代码,我们首先手动运行它来找出 \(120\) 和 \(25\) 的最大公约数。

为此,我们使用带余数的除法。

步骤 1: 我们开始用 \(120\) 除以 \(25\)

\[ \begin{equation} \begin{aligned} 120 & = 4 \cdot 25 + 20 \end{aligned} \end{equation} \]

\(25\) 能在 \(120\) 中容纳多少次?是 4 次,对吧?\(4 \cdot 25\) 等于 100。我们通过从 120 中减去 100 来得到余数 20。

步骤 2: 我们在下一步中使用上一步的余数 20 来除以 25

\[ \begin{equation} \begin{aligned} 25 & = 1 \cdot 20 + 5 \end{aligned} \end{equation} \]

我们可以在 25 中容纳 20 一次。我们通过从 25 中减去 20 来得到余数 5。

步骤 3: 在下一步计算中,我们将 20 除以之前的余数 5

\[ \begin{equation} \begin{aligned} 20 & = 4 \cdot 5 + 0 \end{aligned} \end{equation} \]

我们得到余数 0,这意味着计算已完成。

\(120\) 和 \(25\) 的最大公约数是 \(5\)。


欧几里得算法的实现

要使用除法找到最大公约数,我们将继续运行该算法,直到计算出的余数为 \(0\)。

这相当于说,我们只要 \(b\) 不等于 0 就继续运行该算法。这就是为什么 b != 0 是下面 while 循环的条件。

示例

使用欧几里得算法查找 120 和 25 的最大公约数

def gcd_division(a, b):
    while b != 0:
        remainder = a % b
        print(f"{a} = {a//b} * {b} + {remainder}")
        a = b
        b = remainder
    return a

a = 120
b = 25
print("The Euclidean algorithm using division:\n")
print(f"The GCD of {a} and {b} is: {gcd_division(a, b)}")
运行示例 »

原始欧几里得算法

与我们上面使用的除法不同,2000 多年前在《几何原本》中描述的原始欧几里得算法使用减法。

使用减法查找最大公约数。

结果:

{{ msgDone }}

计算

欧几里得算法(减法)的工作原理

  1. 从两个初始数字 \(a\) 和 \(b\) 开始。
  2. 找出差值 \( a-b=c\)。差值 \(c\) 与 \(a\) 和 \(b\) 共享相同的最大公约数。
  3. 取 \(a\), \(b\), 和 \(c\) 中最小的两个数字,找出它们之间的差值。
  4. 重复步骤 2 和 3,直到差值为 \(0\)。
  5. 计算出的倒数第二个差值就是最大公约数。

使用减法而不是除法速度较慢,但除法和减法方法都使用相同的数学原理。

数字 \(a\) 和 \(b\) 的最大公约数,也等于 \(a\) 和 \(b\) 之间差值 \(a-b\) 的最大公约数。

这只需几行即可证明。

数字 \(a\) 和 \(b\) 有一个最大公约数 \(x\)。

这意味着 \(a\) 和 \(b\) 都可以这样分解:

\[ \begin{equation} \begin{aligned} a & = k \cdot x \\ b & = l \cdot x \end{aligned} \end{equation} \]

分解后,从 \(a\) 中减去 \(b\) 会得到一个非常有趣的结果:

\[ \begin{equation} \begin{aligned} a-b & = k \cdot x - l \cdot x \\ & = (k-l) \cdot x \end{aligned} \end{equation} \]

我们可以看到,\(a\) 和 \(b\) 的最大公约数(\(x\)) 也是 \(a\) 和 \(b\) 之间差值 \(a-b\) 的最大公约数!

这个原理是欧几里得算法工作的根本原因,它使其成为可能。


使用减法查找最大公约数

根据上述原理,即 \(a\) 和 \(b\) 之间的差值也具有相同的最大公约数,我们可以使用减法来查找最大公约数,就像欧几里得的原始算法那样。

让我们使用减法来查找 \(120\) 和 \(25\) 的最大公约数。

\[ \begin{equation} \begin{aligned} 120 - 25 & = 95 \end{aligned} \end{equation} \]

根据已经描述的数学原理,数字 \(120\)、\(25\) 和 \(95\) 都共享相同的最大公约数。

这意味着我们可以通过从 \(95\) 中减去 \(25\) 来进一步简化我们的问题。

\[ \begin{equation} \begin{aligned} 95 - 25 & = 70 \end{aligned} \end{equation} \]

如果我们继续这样做,总是取上一步中最小的两个数字并找出它们之间的差值,我们会得到这些计算:

\[ \begin{equation} \begin{aligned} 70 - 25 & = 45 \\ 45 - 25 & = 20 \\ 25 - 20 & = 5 \\ 20 - 5 & = 15 \\ 15 - 5 & = 10 \\ 10 - 5 & = \underline{\textbf{5}} \\ 5 - 5 & = 0 \end{aligned} \end{equation} \]

当差值为 \(0\) 时,使用减法的欧几里得算法就完成了。

在倒数第二次计算中,我们看到 \(120\) 和 \(25\) 的最大公约数是 \(5\)。

现在我们已经学会了如何用手计算最大公约数(减法),在编程语言中实现它就更容易了。


使用减法的欧几里得算法实现

要使用减法找到最大公约数,我们将继续运行该算法,直到 \(a\) 和 \(b\) 之间的差值为 \(0\),正如我们刚刚看到的。

这相当于说,我们只要 \(a\) 和 \(b\) 的值不同就继续运行该算法。这就是为什么 a != b 是下面 while 循环的条件。

示例

使用减法找到 120 和 25 的最大公约数(欧几里得算法)

def gcd_subtraction(a, b):
    while a != b:
        if a > b:
            print(f"{a} - {b} = {a-b}")
            a = a - b
        else:
            print(f"{b} - {a} = {b-a}")
            b = b - a
    return a

a = 120
b = 25
print("The Euclidean algorithm using subtraction:\n")
print(f"The GCD of {a} and {b} is: {gcd_subtraction(a, b)}")
运行示例 »

比较减法和除法方法

为了更好地理解除法方法在查找最大公约数方面的优势,以及这些方法是如何相似的,我们将

  1. 使用减法找到 \(120\) 和 \(25\) 的最大公约数。
  2. 使用带余数的除法找到 \(120\) 和 \(25\) 的最大公约数。
  3. 比较减法和除法方法。

1. 使用减法

使用减法查找 \(120\) 和 \(25\) 的最大公约数

\[ \begin{equation} \begin{aligned} 120 - 25 & = 95 \\ 95 - 25 & = 70 \\ 70 - 25 & = 45 \\ 45 - 25 & = 20 \\ 25 - 20 & = 5 \\ 20 - 5 & = 15 \\ 15 - 5 & = 10 \\ 10 - 5 & = \underline{\textbf{5}} \\ 5 - 5 & = 0 \end{aligned} \end{equation} \]

使用减法,当差值为 \(0\) 时,算法结束。

在倒数第二次计算中,我们看到 \(120\) 和 \(25\) 的最大公约数是 \(5\)。

注意 \(25\) 和 \(5\) 需要被减去很多次,才能找到 GCD。


2. 使用除法

使用带余数的除法查找 \(120\) 和 \(25\) 的最大公约数如下所示:

\[ \begin{equation} \begin{aligned} 120 & = 4 \cdot 25 + 20 \\ 25 & = 1 \cdot 20 + \underline{\textbf{5}} \\ 20 & = 4 \cdot 5 + 0 \end{aligned} \end{equation} \]

使用除法,当余数为 \(0\) 时,欧几里得算法就完成了。

之前的余数 \(5\) 是 \(120\) 和 \(25\) 的最大公约数。


3. 比较

看看上面提到的减法和除法方法。

为了更清楚地看到除法计算与减法计算基本上是相同的,我们可以这样写带余数的除法计算:

\[ \begin{equation} \begin{aligned} 120 - 4 \cdot 25 & = 20 \\ 25 - 1 \cdot 20 & = \underline{\textbf{5}} \\ 20 - 4 \cdot 5 & = 0 \end{aligned} \end{equation} \]

使用减法,\(25\) 总共从 \(120\) 中减去了 4 次,而除法方法仅用一步就完成了。

类似地,减法方法将 5 减去了 4 次,而除法方法仅用一次计算就完成了相同的操作。

正如您所见,这些方法做的事情是相同的,除法方法只是在同一次计算中进行了多次减法,从而更快地找到了最大公约数。



×

联系销售

如果您想将 W3Schools 服务用于教育机构、团队或企业,请发送电子邮件给我们
sales@w3schools.com

报告错误

如果您想报告错误,或想提出建议,请发送电子邮件给我们
help@w3schools.com

W3Schools 经过优化,旨在方便学习和培训。示例可能经过简化,以提高阅读和学习体验。教程、参考资料和示例会不断审查,以避免错误,但我们无法保证所有内容的完全正确性。使用 W3Schools 即表示您已阅读并接受我们的使用条款Cookie 和隐私政策

版权所有 1999-2024 Refsnes Data。保留所有权利。W3Schools 由 W3.CSS 提供支持