【发布时间】:2015-02-18 15:48:33
【问题描述】:
我正在从非常基础的角度学习 Erlang,但遇到了尾递归函数的问题。我希望我的函数接收一个列表并返回一个新列表,其中 element = element + 1。例如,如果我发送 [1,2,3,4,5] 作为参数,它必须返回 [2,3,4 ,5,6]。问题是当我发送确切的参数时,它返回 [[[[[[]|2]|3]|4]|5]|6]。
我的代码是这样的:
-module(test).
-export([test/0]).
test()->
List = [1,2,3,4,5],
sum_list_2(List).
sum_list_2(List)->
sum_list_2(List,[]).
sum_list_2([Head|Tail], Result)->
sum_list_2(Tail,[Result|Head +1]);
sum_list_2([], Result)->
Result.
但是,如果我将我的功能更改为:
sum_list_2([Head|Tail], Result)->
sum_list_2(Tail,[Head +1|Result]);
sum_list_2([], Result)->
Result.
它输出 [6,5,4,3,2] 没问题。为什么该函数不能反过来工作([Result|Head+1] 输出 [2,3,4,5,6])?
PS:我知道这个特殊问题可以通过列表推导解决,但我想通过递归来解决。
【问题讨论】:
-
Erlang 中很常见的做法是在对列表进行操作后简单地
lists:reverse/1来解决这个问题。 -
好的,谢谢,但这似乎不是很理想。不过,短名单不会有问题。
-
请参阅learnyousomeerlang.com/recursion 以获得有关 Erlang 尾递归的良好指南。它实际上声称相反 - 内置的
lists:reverse/1函数将为更长的列表提供更多好处。 -
我实际上是通过该指南学习 Erlang,但我找不到解决问题的实际方法。我想我将不得不阅读更多关于它的信息。谢谢
-
另外,请查看ferd.ca/erlang-s-tail-recursion-is-not-a-silver-bullet.html,了解有关主体与尾递归的一些信息。对于这个特定问题,我对主体与尾递归(加上列表反转)进行了基准测试,两者本质上是并驾齐驱的。正如其中一个答案所建议的那样,使用 ++ 的速度要慢得多。在对 10000 个元素的快速测试中,运行时间要长 1000 倍。
标签: recursion erlang tail-recursion tail