Erlang中的列表创建

6

我正在阅读Cesarini的《Erlang编程》,遇到了一些奇怪的列表创建问题。在第3-2练习中,我编写了两个类似的函数。

create( 0 ) -> [];
create( N ) when N > 0 -> [ N | create( N-1 ) ].

reverse_create( 0 ) -> [];
reverse_create( N ) when N > 0 -> [ reverse_create( N-1 ) | N ].

所以create(3)生成了我期望的结果。

练习3:create(3)。
[3,2,1]

但reverse_create没有生成我期望的列表。

练习3:reverse_create(3)。
[[[[]|1]|2]|3]

我需要做出哪些改变,才能使reverse_create(3)返回[1,2,3]呢?谢谢您的解释。


好的,示例已经运行成功了。你有什么线索可以解释为什么上面两个相似的函数返回如此不同的答案吗?为什么 create 函数会返回一个干净的列表,而 reverse_create 函数会返回列表的列表呢? - Superpolock
你可以在这里阅读解释:http://learnyousomeerlang.com/starting-out-for-real#lists,也可以参考这些链接:https://dev59.com/YE_Sa4cB1Zd3GeqP8gVc 和 https://dev59.com/anI-5IYBdhLWcg3wTWj4 - Peer Stritzinger
5个回答

5

reverse_create返回一个列表,你正在使用它作为头元素创建列表,这会导致嵌套列表。尝试这个解决方案:

reverse_create( 0 ) -> [];
reverse_create( N ) when N > 0 -> reverse_create( N-1 ) ++ [N].

编辑:更好的实现方式是:

reverse_create2(N) -> reverse_create_helper(N, []).

reverse_create_helper(0, Acc) ->
    Acc;
reverse_create_helper(N, Acc) ->
    reverse_create_helper(N-1, [N|Acc]).

1
它可以将一个O(N)的任务变成一个漂亮的O(N^2)。 - Hynek -Pichi- Vychodil
我已经按照你正确指出的进行了编辑,因为++会复制左操作数。 - Chandra Patni

3
通常像reverse_create这样的函数会使用累加器以尾递归的方式完成。
reverse_create(N) ->
    reverse_create(N, []).

reverse_create(0, Acc) ->
    Acc;
reverse_create(N, Acc) when N > 0 ->
    reverse_create(N - 1, [N | Acc]).

2
当然,你总是可以这样做:

reverse_create(N) -> lists:reverse(create(N)).

这实际上可以运行得更快。但这显然不是本练习的目的。 :)

1

我正在阅读同一本书,所以我并不比你更专家,但这对我有效...

create(0) -> [];
create(N) when N > 0 -> create(N-1) ++ [N].

reverse_create(0) -> [];
reverse_create(N) when N > 0 -> [N|create(N-1)].

0

这是



    reverse_create(0) -> [];
    reverse_create(N) ->
        list_create_1(1, N, []).
list_create_1(I, N, List) when N >= I -> list_create_1(I + 1, N, [I | List]); list_create_1(_, _, List) -> List.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接