【问题标题】:Is there any way to perform this type of recursion in C++ or python?有没有办法在 C++ 或 python 中执行这种类型的递归?
【发布时间】:2021-09-19 19:29:08
【问题描述】:

假设我有一个名为my_func(a,b,s,t) 的函数。假设,我希望 ab 按值传递,但我希望 st 按引用传递。如,我想知道如何传递让我们说(4,5,s',t')。该函数通过调用my_func(a/2,b/2,s/2,t/2) 来执行计算。问题是,在递归的“底部”有一个基本情况,它为st 提供具体值。

让我举一个小例子:

def e_euclid(a,b,s,t):
    
if (a == b):
    s = 4
    t = -3
    return a


if (a%2 == 0 and b%2 == 0):
    
    if (s%2 == 0 and t%2 == 0):
        return 2*e_euclid(a/2,b/2,s/2,t/2)
    else:
        return 2*e_euclid(a/2,b/2,(s+b)/2,(t-a)/2)
...

因此,我将此函数称为e_euclid(a,b, something, something),但随后我必须为st 提供具体值。你们能看出我在这里要做什么吗?

在我返回 (s,t) 的地方进行递归会导致我不想执行的艰难计算,所以我想这样做。

【问题讨论】:

  • 通过值传递 6 个参数 - a、b、s 和 t,以及通过引用传递 s 和 t;将最后两个向下递归调用保持不变。或者,让函数返回 {a, s, t} 的元组而不是单个值,那么您将不需要 by-ref 参数。或者,根本不使用递归:该示例涉及尾递归,它可以被迭代轻松替换。
  • 所以,在递归停止之前,您不想指定第三个和第四个参数的值,然后您想知道第三个和第四个参数的值应该是什么从一开始就是对的。抱歉,没有现代通用编程语言可以这样工作。在表达式 if (s%2 == 0 and t%2 == 0) 中,当这些值直到递归结束时才知道时,您如何期望知道 st 是什么?
  • 你应该迭代地重写它。将列表保留为堆栈,并将值与返回乘法一起压入其中。不会有递归和一个不错的while not stack.is_empty()
  • @SamVarshavchik 我不太了解他们的代码尝试,但请参阅我的答案以了解它是如何完成的。值st(或xy)确实只在递归的底部指定,这是微不足道的,因为它们对应的ab 已经变得微不足道了。在退出递归的过程中,我们确实计算了 xy “从一开始就应该正确”(即,对应于初始的 ab)。跨度>

标签: python c++ recursion euclidean-algorithm


【解决方案1】:

您的代码似乎已损坏,a == bs = 4t = -3 的基本情况 (?) 已经没有意义了。但是请参阅this C++ implementation 和我的 Python 翻译,使用单元素列表而不是 C++ 的引用:

def gcd(a, b, x=[None], y=[None]):
    if b == 0:
        x[0] = 1
        y[0] = 0
        return a
    x1, y1 = [None], [None]
    d = gcd(b, a % b, x1, y1)
    x[0] = y1[0]
    y[0] = x1[0] - y1[0] * (a // b)
    return d

a, b = 123, 321
x, y = [None], [None]
print(gcd(a, b, x, y), x, y, a*x[0] + b*y[0])

输出(Try it online!):

3 [47] [-18] 3

我认为您正在尝试使用算法的二进制版本,这应该是可行的。

【讨论】:

  • 是的,这是正确的。我意识到我一直在尝试做的事情是不可能的,所以我不得不通过返回 (a,b,s,t) 来做到这一点,这相当于这个方法。
猜你喜欢
  • 2019-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-07
  • 2021-09-07
  • 2010-12-14
相关资源
最近更新 更多