2017-08-05 133 views
3

我知道还有其他方法可以避免使用累加器,并且内置的++会将一个列表附加到另一个列表。但是,如果我用累加器构建我自己的尾递归附加函数,有什么方法可以在下面的代码片段之一中使用lists:reverse()?谢谢Erlang将一个列表附加到另一个列表中

joinWithAccumulator2(X,Y) -> 
    joinWithAccumulator2(lists:reverse(X), [], Y). 

joinWithAccumulator2([], [], A) -> 
    A; 

joinWithAccumulator2([X | Xs], [], A) -> 
    joinWithAccumulator2(Xs, [], [ X | A]). 
+1

我不知道erlang是否支持差异列表。 –

+1

虽然arity 3函数中的第二个参数未使用。累加器最终成为第二个列表。 –

+0

我对Erlang并不是很熟悉,但我相信它的列表是渴望的,而不是懒惰 - 所以它需要返回一个完整的列表,而不是一个可以提供下一个按需元素的暂停函数。此外,函数式列表(单链接/不可变)需要通过推送前端元素来扩展堆栈样式。如果这两个条件都成立,你需要以不同的方式反转你的输入列表 - 要么使用'reverse',要么通过递归输入以最后开始(有效地使用栈作为反转列表) – comingstorm

回答

1

构建列表的最快方法是使用[H | T]预先添加元素。所以你做的方式是有效的。如果您的目的是为了避免使用lib库,并且为了使用累加器(请参阅@ juan.facorro注释),您可以先将累加器中的第一个列表反向,然后将其加到第二个列表中:

joinWithAccumulator2(LX, LY) -> 
    joinWithAccumulator2(LX, LY, []). 

% first step reverse LX in LA 
joinWithAccumulator2([X | Xs], LY, LA) -> 
    joinWithAccumulator2(Xs, LY, [X | LA]); 
% second step, when LX is empty, prepend LA to LY (list accumulator2) 
joinWithAccumulator2([], LA2, [A | As]) -> 
    joinWithAccumulator2([], [A | LA2], As); 
% operation done 
joinWithAccumulator2([], A, []) -> 
    A. 
相关问题