如何在不计算额外结果的情况下退出非尾递归?
How to exit a non-tail recursion without computing additional results?
我有一个非尾递归 ( )。我有两个 "correct" 答案,其中一个我认为不是正确答案,但我也在我公认的大量调试打印语句中注意到,尽管找到了答案,但程序在退出递归时仍在计算.有没有办法中断这个或者这两个部分是同一个问题?
def partialDigest(l):
width = max(l)
l.remove(width)
x = [0, width]
place(l, x, width, level=0)
def place(l, x, width, level):
level = level + 1
print('level',level)
if not l:
print('done!', x)
return
y = max(l)
print('y',y)
print('a', [abs(i-y) for i in x], l)
if subset([abs(i-y) for i in x], l):
print('choose a')
print('x',sorted(x))
print('l',sorted(l))
print('append y to x and remove delta(x) from l')
remove_lengths([abs(i-y) for i in x], l)
x.append(y)
print('x',sorted(x))
print('l',sorted(l))
print ('run place')
place(l, x, width, level)
print('remove y from x and add lengths to l')
add_lengths([abs(i-y) for i in x], l)
x.remove(y)
print('b', [abs(i-(width-y)) for i in x], l)
if subset([abs(i-(width-y)) for i in x], l):
print('choose b')
print('x',sorted(x))
print('l',sorted(l))
print('append (width - y) to x and remove lengths from l')
remove_lengths([abs(i-(width - y)) for i in x], l)
x.append(width - y)
print('x',sorted(x))
print('l',sorted(l))
print('run place')
place(l, x, width, level)
print('remove (width - y) from x and add lengths to l')
add_lengths([abs(i-(width-y)) for i in x], l)
x.remove(width - y)
else:
print('c')
print x, l
print('return to level', level)
return x, l
def remove_lengths(x, l):
for i in x:
if i in l:
l.remove(i)
return l
def add_lengths(x, l):
for i in x:
if i != 0:
l.append(i)
return l
def subset(list1, list2):
x = True
for i in list1:
if i not in list2:
x = False
return x
l = [2, 2, 3, 3, 4, 5, 6, 7, 8, 10]
print(partialDigest(l))
对于那些感兴趣的人,这是实施 Steven Skiena 对限制性片段映射的部分摘要问题的解决方案的尝试。 Antonio Perez has a generally better, conceptually similar solution 超过 GitHub,但他的实现似乎有同样的问题。
你的代码中可能是递归终止的部分
if not l:
print('done!', x)
return
正在做 pretty much the same as returning None
,而在其他情况下 return 是非 None
的东西。
因此,当您进行递归调用时,只需为此检查 return 值,如果是这种情况,则 return 无需继续进行冗余计算。也就是说,而不是
foo(...) # I'm calling foo
# and continuing unconditionally,
使用
if foo(...) is None: # If someone below me reached the termination
return # Then I will propagate the termination having been reached, and won't continue
这里有一些糟糕的软件工程,但足够好的生物信息学。 Ami 的答案更糟糕,但您可能更容易实施。
您可以 raise
异常来表示计算已完成。一开始,在你的函数之前,你写:
class Done(Exception):
"""Completed recursion and found answer."""
# No body required
所以一旦你知道你有答案,你就去
if Answer found:
# print it
raise Done
然后当你调用整个函数时,它会在找到第一个答案后立即停止所有级别的递归。它也会退出你的整个程序,除非你用 try 块调用函数,
try:
place(l, x, width, level=0)
except Done:
# We expected this, nothing to do
pass
再一次,这是糟糕的软件工程:纯粹主义者可能会生你的气!然而,在更复杂的递归中很容易得到正确的结果,而不必正确地探测所有的退出情况。
我有一个非尾递归 ( )。我有两个 "correct" 答案,其中一个我认为不是正确答案,但我也在我公认的大量调试打印语句中注意到,尽管找到了答案,但程序在退出递归时仍在计算.有没有办法中断这个或者这两个部分是同一个问题?
def partialDigest(l):
width = max(l)
l.remove(width)
x = [0, width]
place(l, x, width, level=0)
def place(l, x, width, level):
level = level + 1
print('level',level)
if not l:
print('done!', x)
return
y = max(l)
print('y',y)
print('a', [abs(i-y) for i in x], l)
if subset([abs(i-y) for i in x], l):
print('choose a')
print('x',sorted(x))
print('l',sorted(l))
print('append y to x and remove delta(x) from l')
remove_lengths([abs(i-y) for i in x], l)
x.append(y)
print('x',sorted(x))
print('l',sorted(l))
print ('run place')
place(l, x, width, level)
print('remove y from x and add lengths to l')
add_lengths([abs(i-y) for i in x], l)
x.remove(y)
print('b', [abs(i-(width-y)) for i in x], l)
if subset([abs(i-(width-y)) for i in x], l):
print('choose b')
print('x',sorted(x))
print('l',sorted(l))
print('append (width - y) to x and remove lengths from l')
remove_lengths([abs(i-(width - y)) for i in x], l)
x.append(width - y)
print('x',sorted(x))
print('l',sorted(l))
print('run place')
place(l, x, width, level)
print('remove (width - y) from x and add lengths to l')
add_lengths([abs(i-(width-y)) for i in x], l)
x.remove(width - y)
else:
print('c')
print x, l
print('return to level', level)
return x, l
def remove_lengths(x, l):
for i in x:
if i in l:
l.remove(i)
return l
def add_lengths(x, l):
for i in x:
if i != 0:
l.append(i)
return l
def subset(list1, list2):
x = True
for i in list1:
if i not in list2:
x = False
return x
l = [2, 2, 3, 3, 4, 5, 6, 7, 8, 10]
print(partialDigest(l))
对于那些感兴趣的人,这是实施 Steven Skiena 对限制性片段映射的部分摘要问题的解决方案的尝试。 Antonio Perez has a generally better, conceptually similar solution 超过 GitHub,但他的实现似乎有同样的问题。
你的代码中可能是递归终止的部分
if not l:
print('done!', x)
return
正在做 pretty much the same as returning None
,而在其他情况下 return 是非 None
的东西。
因此,当您进行递归调用时,只需为此检查 return 值,如果是这种情况,则 return 无需继续进行冗余计算。也就是说,而不是
foo(...) # I'm calling foo
# and continuing unconditionally,
使用
if foo(...) is None: # If someone below me reached the termination
return # Then I will propagate the termination having been reached, and won't continue
这里有一些糟糕的软件工程,但足够好的生物信息学。 Ami 的答案更糟糕,但您可能更容易实施。
您可以 raise
异常来表示计算已完成。一开始,在你的函数之前,你写:
class Done(Exception):
"""Completed recursion and found answer."""
# No body required
所以一旦你知道你有答案,你就去
if Answer found:
# print it
raise Done
然后当你调用整个函数时,它会在找到第一个答案后立即停止所有级别的递归。它也会退出你的整个程序,除非你用 try 块调用函数,
try:
place(l, x, width, level=0)
except Done:
# We expected this, nothing to do
pass
再一次,这是糟糕的软件工程:纯粹主义者可能会生你的气!然而,在更复杂的递归中很容易得到正确的结果,而不必正确地探测所有的退出情况。