2017-09-27 53 views
-3

我正在做關於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). 
+0

你需要什麼幫助嗎? –

+0

你到現在爲止嘗試過什麼? –

+0

我正在關注這個想法。首先,我使用平坦化函數提取列表中的所有元素。然後,我使用函數reverse創建一個反轉列表。我目前的困難是我無法用反向列表中的元素替換輸入列表中的元素。 –

回答

1

首先,讓我們來看一個簡單的反向作用可能看起來怎麼樣,沒有功能。

帶有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的執行是相對直截了當的。如果你不明白這裏發生了什麼,你應該讀一下listsrecursion

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-expressionspattern-matching

+0

感謝您的詳細解釋。但是,當我嘗試運行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 ] –

+0

你確定嗎?這看起來不正確。在你的解決方案中,'2'是第一個內部列表的一部分,因爲在這個例子中它是最外層列表的一部分。 '8'也是如此,它是外部列表的一部分,它應該是第一個內部列表的一部分。 –

+0

哎呀,這是我的錯。你是對的。對於那個很抱歉!但是,你能告訴我修改上述函數的方法,以便它可以返回[9,8,[7,6,[5,4,3],2],1]? –