使用Python中的递归函数计算扩展的gcd

时间:2012-09-22 13:14:31

标签: python recursion

我得到了函数gcd,其定义如下:

def gcd(a, b):
    if (0 == a % b):
        return b
    return gcd(b, a%b)

现在我被要求编写递归函数gcd2(a,b),该函数返回三个数字(g, s, t)的列表,其中g = gcd(a, b)g = s*a + t*b

这意味着您要在(a and b)函数中输入两个值gcd(a, b)。它返回的值等于下一个函数中的g

然后将这些相同的ab值调入gcd2(a, b)。然后使用递归部分来查找s和t的值,以便g = s*a + t*b

我不知道如何处理这个因为我无法真正想象“停止条件”会是什么,或者我究竟要通过递归循环来实际查找{{ 1}}和s。任何人都可以帮助我吗?

4 个答案:

答案 0 :(得分:2)

关键的洞察力是我们可以向后工作,在递归中为每个st找到ab。所以说我们有a = 21b = 15。我们需要使用多个值来完成每次迭代 - abb % a c其中a = c * b + a % b 。首先,让我们考虑基本GCD算法的每一步:

21 = 1 * 15 + 6
15 = 2 * 6  + 3
6  = 2 * 3  + 0 -> end recursion

所以我们的gcd(g)是3.一旦我们得到了,我们就确定st为6和3.为此,我们从{{1}开始},用g

表达
(a, b, s, t = 3, 0, 1, -1)

现在我们要消除0期。从基本算法的最后一行,我们知道0 = 6 - 2 * 3:

3  = 1 * 3 + -1 * 0

简化,我们得到

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 == -1t == 3a = 6。因此,鉴于b = 3a的值,b应返回gcd2

现在我们退回到递归,我们想要消除3个术语。从基本算法的倒数第二行开始,我们知道3 = 15 - 2 * 6.再次简化和交换(慢慢地,以便您可以清楚地看到步骤......):

(3, -1, 3)

因此,对于这种递归级别,我们返回3 = -1 * 6 + 3 * (15 - 2 * 6) 3 = -1 * 6 + 3 * 15 - 6 * 6 3 = -7 * 6 + 3 * 15 3 = 3 * 15 + -7 * 6 。现在我们要消除6个学期。

(3, 3, -7)

瞧,我们已经为21和15计算了3 = 3 * 15 + -7 * (21 - 1 * 15) 3 = 3 * 15 + 7 * 15 - 7 * 21 3 = 10 * 15 - 7 * 21 3 = -7 * 21 + 10 * 15 s

如图所示,递归函数如下所示:

t

请注意,出于我们的目的,使用略有不同的基本案例简化了事情:

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

答案 1 :(得分:1)

基本情况(停止条件)是:

if a%b == 0:
    # a = b*k for the integer k=a/b
    # rearranges to b = -1*a + (k+1)*b
    #             ( g =  s*a + t*b )
    return (b, -1, a/b+1) # (g, s, t)

然而,练习是重写递归部分:

g1, s1, t1 = gcd(b, a%b) # where g1 = s1*b + t1*(a%b)
g, s, t = ???            # where g = s*a + t*b
return (g, s, t)

g1s1t1 ... 而言,归结为以{{1}为单位重写a%b }和a

答案 2 :(得分:0)

“在Python中写一个递归函数”,至少在CPython中,为此哭泣:注意http://docs.python.org/library/sys.html#sys.getrecursionlimit。在我看来,这是这个问题最重要的答案之一。请自行研究一下这个话题。此外,这个主题可能很有见地:Python: What is the hard recursion limit for Linux, Mac and Windows?

总之,尽可能尝试在Python中使用迭代而不是递归方法。

答案 3 :(得分:0)

它基于Euclidian算法,使用更好的while循环连续递归甚至更好,更少执行

def gcd(m,n):
#assume m>= n
if m <n:
    (m,n) = (n,m)
if (m%n) == 0:
    return(n)
else:
    diff =m-n
    #diff >n ?Possible!
    return(gcd(max(n,diff),min(n,diff)))

while循环可以更好

def gcd(m,n):
if m<n :
    (m,n) =(n,m)
while (m%n) !=0:
    diff =m-n
    (m,n) =(max(n,diff),min(n,diff))
return(n)