Python 将递归函数重写为尾部递归函数

Python 将递归函数重写为尾部递归函数,python,algorithm,recursion,stack-overflow,tail-recursion,Python,Algorithm,Recursion,Stack Overflow,Tail Recursion,问题:通过掷骰子一次或多次来计算构造sumn的方法数。每次投掷产生的结果介于1和6之间 解决方案:我已经为它编写了一个递归解决方案,它输出正确的答案。对于较大的n值,它应该会导致堆栈溢出。所以我想避免它,并使用尾部递归方法重写代码。这是我的密码: def numWays(n, arr): answer = 0 for item in arr: if item <= n: if n == item: answer += 1 else:

问题:通过掷骰子一次或多次来计算构造sum
n
的方法数。每次投掷产生的结果介于1和6之间

解决方案:我已经为它编写了一个递归解决方案,它输出正确的答案。对于较大的
n
值,它应该会导致堆栈溢出。所以我想避免它,并使用尾部递归方法重写代码。这是我的密码:

def numWays(n, arr):
  answer = 0
  for item in arr:
    if item <= n:
      if n == item:
        answer += 1
      else:
        answer += numWays(n-item, arr)

  return answer

li = [i for i in range(1,7)]
print(numWays(5, li)) #example n=5
def天数(n,arr):
答案=0
对于arr中的项目:

如果item,解决堆栈溢出问题的一种方法是手动模拟callstack

def天数(n,arr):
调用_stack=[(n,arr)]
答案=0
调用堆栈时:
n、 arr=call_stack.pop(0)
对于arr中的项目:

如果项这里有一个简单的解决方案,没有递归,没有什么,O(N):

结果:

[1, 1, 2, 4, 8, 16, 32, 63, 125, 248, 492, 976, 1936, 3840, 7617, 15109]
14527490260516100855695859704819627818108010882741117227956927412305738742399171256642436462028811566617818991926058940988565927870172608545709804976244851391054850231415387973537361

可以很容易地计算出N=50000或500000的转鼓数。

你有没有看过关于为什么尾部递归在python中不重要的内容,以及设置递归的最大级别的方法?@BalajiAmbresh:实际上我的重点是将递归重写为尾部递归。我最初是用Scala编写的,但Python更为人所知,所以这里用它作为例子。你能解释一下“构造和n的方法”是什么意思吗?特别是ePi272314中的“求和n”:例如,如果n=3,则有4种方式:a)1+1+1 b)1+2 c)2+1 d)3绞。但我实际上想学习如何将递归函数转换为一般的尾部递归函数。以问题、代码和Python为例,这样问题就不会变得过于理论化。也许我应该特别提到这一点。
#!/usr/bin/env python

DICE = 6    # how many sides our dice has

rolls = [1]
for i in range(1,800) :
    rolls.append(sum(rolls[-min(i,DICE):]))

print rolls[:16]  # print results for the first 16 (zero-based!!)
print rolls[610]  # print result for 610 steps
[1, 1, 2, 4, 8, 16, 32, 63, 125, 248, 492, 976, 1936, 3840, 7617, 15109]
14527490260516100855695859704819627818108010882741117227956927412305738742399171256642436462028811566617818991926058940988565927870172608545709804976244851391054850231415387973537361