我正在练习Erlang,我无法实现这个功能。
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)
首先,让我们看一下简单的反向函数是什么样子,没有深特征。
具有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
(Head)是它的第一个元素,而T
(Tail)是列表的其余部分。我们再次使用tail作为第一个参数调用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
是列表。如果它是一个列表,我们必须在递归执行时再次在deep_reverse
上调用H
。
如果您难以理解语法,请参阅以下链接:case-expressions和pattern-matching