2017-09-27 50 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]? –