这个递归的结果树不是我的意思,这可能证明我不完全理解递归中列表/元组的行为。如果有人可以解释我在这个例子中做错了什么,并解释了正确的思考方式我会非常感激。
move([],{Main, One, Two}) ->
{Main, One, Two};
move([X|Xr], {Main, One, Two}) ->
[{Main, One, Two}, move(Xr, single(X, {Main, One, Two}))].
期望的结果(一个包含3个元组的列表):
[{[a,b],[],[]}, {[a],[b],[]}, {[],[b],[a]}, {[b],[],[a]}]
实际结果(包含元组和列表的列表,包含元组和列表......):
[{[a,b],[],[]},[{[a],[b],[]},[{[],[b],[a]},[{[b],[],[a]}]]]]
答案 0 :(得分:6)
你有两个问题:
|
,如@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
答案 1 :(得分:0)
在撰写像这样的列表时,您希望使用|
而不是,
:
move([X|Xr], {Main, One, Two}) ->
[{Main, One, Two} | move(Xr, single(X, {Main, One, Two}))].
递归调用会返回一个列表,除非您使用|
将它们展平,否则它将更深入地嵌套。它与模式匹配[X|Xr]
中的概念相同,只是反向操作。