Recursion Erlang-递归后列表/元组层次结构的问题
这个递归的结果树不是什么I什么,这可能证明我不完全理解递归中列表/元组的行为。如果有人能解释我在这个例子中做错了什么,并解释正确的思考方式,我将非常感激Recursion Erlang-递归后列表/元组层次结构的问题,recursion,erlang,Recursion,Erlang,这个递归的结果树不是什么I什么,这可能证明我不完全理解递归中列表/元组的行为。如果有人能解释我在这个例子中做错了什么,并解释正确的思考方式,我将非常感激 move([],{Main, One, Two}) -> {Main, One, Two}; move([X|Xr], {Main, One, Two}) -> [{Main, One, Two}, move(Xr, single(X, {Main, One, Two}))]. 所需结果(一个包含3个元组的列表):
move([],{Main, One, Two}) ->
{Main, One, Two};
move([X|Xr], {Main, One, Two}) ->
[{Main, One, Two}, move(Xr, single(X, {Main, One, Two}))].
所需结果(一个包含3个元组的列表):
实际结果(包含元组和列表的列表,包含元组和列表…):
在编写这样的列表时,您希望使用
|
而不是,
:
move([X|Xr], {Main, One, Two}) ->
[{Main, One, Two} | move(Xr, single(X, {Main, One, Two}))].
递归调用返回一个列表,该列表将嵌套得越来越深,除非您使用|
将它们展平一点。这与模式匹配中的概念相同,只是使用了一个反向操作。您有两个问题:
|
而不是@nmichaels提到的,
move/2
返回一个列表,因此终止子句也必须返回一个列表。在您的示例中没有看到这一点,因为第一个问题隐藏了它move([X|Xr], {Main, One, Two}) ->
[{Main, One, Two} | move(Xr, single(X, {Main, One, Two}))];
move([], {Main, One, Two}) ->
[{Main, One, Two}].
我改变了条款的顺序,因为我个人更喜欢这样写。在这种情况下没有根本区别。我假设single/2
返回一个元组
实际上,您可以通过从move/2
中删除元组的所有知识来优化此代码,因为它从未实际使用内部结构。因此:
move([X|Xr], Tuple) ->
[Tuple | move(Xr, single(X, Tuple))];
move([], Tuple) ->
[Tuple].
我试过了,但结果会更好,但并不完美:
[{[a,b],[]},{[a],[b],[b],[a]}{[b],[a]}{[b],[a]}]
答案中仍然有“|”。它将X应用于主列表,1和2,并返回{MainX,OneX,TwoX},一个包含3个列表的元组。解决了它!我添加了一个累加器(我想),一个空列表,我在其中存储状态,而不是在从递归向上添加状态<代码>移动([],元组,Y)->追加(Y,[元组]);move([X | Xr],Tuple,Y)->move(Xr,single(X,Tuple),append(Y,[Tuple])。说这是尾部递归是正确的吗?
move([X|Xr], {Main, One, Two}) ->
[{Main, One, Two} | move(Xr, single(X, {Main, One, Two}))];
move([], {Main, One, Two}) ->
[{Main, One, Two}].
move([X|Xr], Tuple) ->
[Tuple | move(Xr, single(X, Tuple))];
move([], Tuple) ->
[Tuple].