我正在做關於Erlang的練習,我無法實現此功能。Erlang,deep_reverse(Lst)函數
deep_reverse(LST)
反轉L的各級中的元素。例如,如果Lst是[a,[b,c,[d]],e],則深度反轉應返回[e,[[d],c,b],a]。
任何人都可以幫我完成這個練習嗎?
element_reverse(List) ->
Flat = lists:flatten(List),
lists:reverse(Flat).
我正在做關於Erlang的練習,我無法實現此功能。Erlang,deep_reverse(Lst)函數
deep_reverse(LST)
反轉L的各級中的元素。例如,如果Lst是[a,[b,c,[d]],e],則深度反轉應返回[e,[[d],c,b],a]。
任何人都可以幫我完成這個練習嗎?
element_reverse(List) ->
Flat = lists:flatten(List),
lists:reverse(Flat).
首先,讓我們來看一個簡單的反向作用可能看起來怎麼樣,沒有深功能。
帶有1個參數的函數是不夠的,我們需要一個累加器,一個正在轉移到下一個遞歸步驟的值。累加器首先是一個空列表,在遞歸的每一步中,它都會被連續填充。
simple_reverse(List) -> simple_reverse(List, []).
所以,現在我們需要定義一個2參數功能,使得simple_reverse(List, [])
可以被調用。
simple_reverse([H|T], Accu) ->
simple_reverse(T, [H] ++ Accu);
simple_reverse([], Accu) -> Accu.
函數定義的第一部分處理帶有內容的列表。 [H|T]
的意思是,我們有一個列表和H
(頭)是它的第一個元素,而T
(尾)是列表中的其餘部分。我們再次以尾部作爲第一個參數調用simple_reverse
,並首先用累加器頭累加頭值。
第二部分處理列表爲空的情況。當發生這種情況時,我們可以返回累加器(所有先頭積累的值)。
當你明白這裏發生了什麼時,deep_reverse
的執行是相對直截了當的。如果你不明白這裏發生了什麼,你應該讀一下lists和recursion。
deep_reverse(List) -> deep_reverse(List, []).
deep_reverse([H|T], Accu) ->
case H of
[_|_] -> deep_reverse(T, [deep_reverse(H)] ++ Accu);
_ -> deep_reverse(T, [H] ++ Accu)
end;
deep_reverse([], Accu) -> Accu.
下面我們就來看看H
- 值。 H
既可以是列表本身([_|_]
)或其他東西(_
)。遞歸基本上與simple_reverse
相同,除非H
是一個列表。如果它是一個列表,當遞歸執行時,我們必須在H
上再次調用deep_reverse
。
這裏有一些鏈接,如果你很難理解的語法:case-expressions和pattern-matching
感謝您的詳細解釋。但是,當我嘗試運行List = [1,2,[3,4,[5,6,7],8],9]的函數時,結果似乎不正確。它應該返回[9,8,[7,6,[5,4,3],2],1]而不是[9,[8,[7,6,5],4,3],2,1 ] –
你確定嗎?這看起來不正確。在你的解決方案中,'2'是第一個內部列表的一部分,因爲在這個例子中它是最外層列表的一部分。 '8'也是如此,它是外部列表的一部分,它應該是第一個內部列表的一部分。 –
哎呀,這是我的錯。你是對的。對於那個很抱歉!但是,你能告訴我修改上述函數的方法,以便它可以返回[9,8,[7,6,[5,4,3],2],1]? –
你需要什麼幫助嗎? –
你到現在爲止嘗試過什麼? –
我正在關注這個想法。首先,我使用平坦化函數提取列表中的所有元素。然後,我使用函數reverse創建一個反轉列表。我目前的困難是我無法用反向列表中的元素替換輸入列表中的元素。 –