我正在做关于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创建一个反转列表。我目前的困难是我无法用反向列表中的元素替换输入列表中的元素。 –