我正在写一本关于Erlang的书。这是任务:在不使用BIF的情况下编写反向函数。
这就是我的所作所为:
reverse([H | T]) -> [reverse(T) | [H]];
reverse([]) -> [].
以下是此函数返回的内容:
(emacs@localhost)3> examples:reverse([1, 2, 3]).
[[[[],3],2],1]
我无法理解如何让它返回展平列表[3, 2, 1]
。它有可能吗?
答案 0 :(得分:4)
在语法[H | T]中,H是一个元素,T是一个列表(至少对于proplist),在你的代码中[reverse(T) | [H]]
创建一个列表,其中第一个元素是{{1}的结果},以及哪个tail是单个元素列表reverse(T)
。
如果你想以这种方式实现这个功能,你应该使用fenollp提出的语法。
如果你想编写一个有效的代码,你应该避免对部分结果进行多个中间复制,并避免使用non tail recursive calls(为了限制调用堆栈的大小:
[H]
答案 1 :(得分:3)
正如你所说,你只需要压扁。
所以要么使用列表:在你的例子之后追加/ 1:反向/ 1函数,或用reverse([H | T]) -> [reverse(T) | [H]];
替换reverse([H | T]) -> reverse(T) ++ [H];
。
然后,代码在算法上效率非常低,这就是为什么列表:reverse / 1,2是BIF。
答案 2 :(得分:1)
你可以使用折叠:
lists:foldl(fun(X, Acc) -> [X | Acc] end, [], [1,2,3]).
答案 3 :(得分:0)
您不必将结果放在列表中。 这对我来说很好:
reverse([]) -> [];
reverse([H | T]) -> reverse(T) ++ [H].