关键的见解是我们可以向后工作,在递归中找到and for s
each t
。所以说我们有和。我们需要使用几个值—— 、、和where来完成每次迭代。首先,让我们考虑基本 GCD 算法的每一步:a
b
a = 21
b = 15
a
b
b % a
c
a = c * b + a % b
21 = 1 * 15 + 6
15 = 2 * 6 + 3
6 = 2 * 3 + 0 -> end recursion
所以我们的 gcd ( g
) 是 3。一旦有了它,我们就确定6s
和t
3 的 和。为此,我们从 开始,用g
表示(a, b, s, t = 3, 0, 1, -1)
:
3 = 1 * 3 + -1 * 0
现在我们要消除 0 项。从基本算法的最后一行,我们知道 0 = 6 - 2 * 3:
3 = 1 * 3 + -1 * (6 - 2 * 3)
简化,我们得到
3 = 1 * 3 + -1 * 6 + 2 * 3
3 = 3 * 3 + -1 * 6
现在我们交换条款:
3 = -1 * 6 + 3 * 3
所以我们有s == -1
和t == 3
为a = 6
和b = 3
。因此,鉴于 and 的这些值a
,b
应该gcd2
返回(3, -1, 3)
。
现在我们通过递归退一步,我们想要消除第 3 项。从基本算法的倒数第二行,我们知道3 = 15 - 2 * 6。再次简化和交换(慢慢来,这样你可以清楚地看到步骤......):
3 = -1 * 6 + 3 * (15 - 2 * 6)
3 = -1 * 6 + 3 * 15 - 6 * 6
3 = -7 * 6 + 3 * 15
3 = 3 * 15 + -7 * 6
所以对于这个级别的递归,我们返回(3, 3, -7)
. 现在我们要消除 6 项。
3 = 3 * 15 + -7 * (21 - 1 * 15)
3 = 3 * 15 + 7 * 15 - 7 * 21
3 = 10 * 15 - 7 * 21
3 = -7 * 21 + 10 * 15
瞧,我们已经计算了 21s
和t
15。
如此示意性地,递归函数将如下所示:
def gcd2(a, b):
if (0 == a % b):
# calculate s and t
return b, s, t
else:
g, s, t = gcd2(b, a % b)
# calculate new_s and new_t
return g, new_s, new_t
请注意,出于我们的目的,使用稍微不同的基本情况可以简化事情:
def gcd2(a, b):
if (0 == b):
return a, 1, -1
else:
g, s, t = gcd2(b, a % b)
# calculate new_s and new_t
return g, new_s, new_t