您认为编写此ackermann function值的方法的最佳方法是什么?这个函数结合了几个“捷径”,用于计算值的最简单方法,通过减少递归调用的数量来大大加快计算速度,但最终会得到一个长表达式。
版本使用:
对你来说,任何版本似乎都更好吗?为什么?我很好奇。
>>> def ack4(M, N):
return (N + 1) if M == 0 else \
(N + 2) if M == 1 else \
(2*N + 3) if M == 2 else \
(8*(2**N - 1) + 5) if M == 3 else \
ack4(M-1, 1) if N == 0 else \
ack4(M-1, ack4(M, N-1))
>>> def ack2(M, N):
return (N + 1) if M == 0 else (
(N + 2) if M == 1 else (
(2*N + 3) if M == 2 else (
(8*(2**N - 1) + 5) if M == 3 else (
ack2(M-1, 1) if N == 0 else
ack2(M-1, ack2(M, N-1))))))
>>> def ack3(M, N):
return ((N + 1) if M == 0 else
(N + 2) if M == 1 else
(2*N + 3) if M == 2 else
(8*(2**N - 1) + 5) if M == 3 else
ack3(M-1, 1) if N == 0 else
ack3(M-1, ack3(M, N-1)))
>>> ack2(4, 2) == ack3(4, 2) == ack4(4, 2)
True
>>>
答案 0 :(得分:4)
在一个简单的elif链中嵌套有什么问题?
def ack5(m, n):
if m == 0:
return (n + 1)
elif m == 1:
return (n + 2)
elif m == 2:
return (2 * n + 3)
elif m == 3:
return (8 * ( 2 ** n - 1) + 5)
elif n == 0:
return ack5(m - 1, 1)
else:
return ack5(m - 1, ack5(m, n - 1))
Python代码对于程序员来说应该是可读的,因此它更像是一个个人选择问题。如果我必须选择你的3个例子中的一个,我会选择ack4,因为那些反斜杠表明一切都是一个很大的陈述而没有像我所说的支架那样膨胀表达。
答案 1 :(得分:3)
不要害怕多次退货。另外,尽量避免使用大写字母表示局部变量。
def ack4(m, n):
if m == 0:
return n + 1
if m == 1:
return n + 2
if m == 2:
return 2 * n + 3
if m == 3:
return (8 * ( 2 ** n - 1) + 5)
if n == 0:
return ack5(m - 1, 1)
return ack5(m - 1, ack5(m, n - 1))
答案 2 :(得分:0)
def ack5(m, n):
if m == 0: return n + 1
if m == 1: return n + 2
if m == 2: return 2*n + 3
if m == 3: return 8*(2**n - 1) + 5
if n == 0: return ack5(m-1, 1)
return ack5(m-1, ack5(m, n-1))