2017-08-05 164 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. 
相關問題