我创建了一个迭代函数,该函数输出4 3 2 1 0 1 2 3 4。
def bounce2(n):
s = n
for i in range(n):
print(n)
n = n-1
if n <= 0:
for i in range(s+1):
print(-n)
n = n-1
return
bounce2(4)
如果我想要一个功能完全相同的递归函数,我应该怎么想?
答案 0 :(得分:11)
尝试一下:
def bounce(n):
if n >= 0:
print(n)
bounce(n - 1)
if n:
print(n)
bounce(4)
输出将是: 4 3 2 1个 0 1个 2 3 4
答案 1 :(得分:2)
预期输出:
4 3 2 1 0 1 2 3 4
让我把它放在图表中:
4
3
2
1
0
1
2
3
4
我们将其放入代码中
def bounce(n):
print(n)
if n:
bounce(n - 1)
print(n)
或者我可以将它视为遍历树-上下(在这种情况下,树是线性的):
↓
4
↓ | ↑
3
↓ | ↑
2
↓ | ↑
1
↓ | ↑
0
如何执行tree traversal有多种方法,我将在这里选择DFS-depth-first search。
DFS伪代码:
procedure DFS(G,v):
label v as discovered
for all edges from v to w in G.adjacentEdges(v) do
if vertex w is not labeled as discovered then
recursively call DFS(G,w)
实际上,它是为图形设计的,而不仅仅是树木。对于树木,我们不必做“被发现的标签”部分。
将此DFS转换为Python:
def dfs(node):
for child_node in node:
dfs(child_node)
在4 3 2 1 0
情况下,我们不需要for
,因为只有一个或零个子节点-n - 1
,只要n > 0
:
def our_dfs(n):
if n > 0:
child_node = n - 1
our_dfs(child_node)
但这只是遍历,还没有真正有用的方法。让我们注入我们的“业务逻辑”:
def bounce(n):
# stuff that happens before we go down
print(n)
# descend
if n > 0:
child_node = n - 1
bounce(child_node)
# stuff that happens after we are back from processing the subtree
if n > 0:
print(n)
因为我们相信良好的工艺水平,并且希望产生清晰的代码(好吧,我现在开始在开玩笑),所以我们希望只做一件事的函数-DFS的一个函数,一个代表我们的树的函数,一个单独的函数( s)了解我们的业务逻辑:
def dfs(node, child_factory, before_stuff, after_stuff):
before_stuff(node)
for child_node in get_child_nodes(node):
dfs(child_node, child_factory, before_stuff, after_stuff)
after_stuff(node)
def get_child_nodes(n):
if n:
yield n - 1
def print_before(node):
print(node)
def print_after(node):
if node:
print(node)
def bounce(n):
dfs(n, get_child_nodes, print_before, print_after)
bounce(4)
也许我们可以通过使用嵌套函数来简化dfs
函数:
def dfs(node, child_factory, before_stuff, after_stuff):
def f(node):
before_stuff(node)
for child_node in get_child_nodes(node):
f(child_node)
after_stuff(node)
f(node)
嘿,看一下,我还有一个主意...我们可以将其修改为一个返回可以执行DFS的函数(closure)的函数:
def make_dfs(child_factory, before_stuff, after_stuff):
def dfs(node):
before_stuff(node)
for child_node in get_child_nodes(node):
dfs(child_node)
after_stuff(node)
return dfs
所以跳出程序现在变为:
def get_child_nodes(n):
if n:
yield n - 1
def print_before(node):
print(node)
def print_after(node):
if node:
print(node)
def make_dfs(child_factory, before_stuff, after_stuff):
def dfs(node):
before_stuff(node)
for child_node in get_child_nodes(node):
dfs(child_node)
after_stuff(node)
return dfs
bounce = make_dfs(get_child_nodes, print_before, print_after)
bounce(4)
那么,这个解决方案有什么优点呢? (请注意:部分还是在开玩笑)您知道,Python有一个recursion limit。可以嵌套多少个函数调用的数量是有限的,并且这个数量非常低。使用递归函数处理未知输入是一个很大的缺点(有时甚至是安全问题)。所以现在怎么办?好吧,只需将make_dfs
的实现替换为基于堆栈的内容(请参见DFS Wikipedia页面),而不要使用递归。做完了您无需触摸其他任何东西。
答案 2 :(得分:1)
@ mehrdad-pedramfar发布了一个很好的答案。您也可以尝试更详细的方法:
def my_recursion(current_value, first_portion):
if current_value == 5:
return
print(current_value)
if current_value == 0 or not first_portion:
my_recursion(current_value + 1, False)
elif first_portion:
my_recursion(current_value - 1, True)
my_recursion(4, True)
答案 3 :(得分:-1)
与第一个基本相同。输出是不同的-您将得到双0。 只是为了显示您可以在递归调用之前和之后进行打印。
def bounce(n):
if n >= 0:
print(n)
bounce(n - 1)
print(n)
3 2 1个 0 0 1个 2 3