Erlang,deep_reverse(Lst)函数

时间:2017-09-27 11:13:52

标签: erlang

我正在练习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).

1 个答案:

答案 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的实施相对简单。如果您不了解此处发生的情况,请阅读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是列表。如果它是一个列表,我们必须在递归执行时再次在deep_reverse上调用H

如果您难以理解语法,请参阅以下链接:case-expressionspattern-matching