2017-09-27 11 views
-3

私はErlangについて練習をしており、この関数を実装することはできません。Erlang、deep_reverse(Lst)関数

deep_reverse(Lstの)

は、すべてのレベルでLの要素を反転します。

たとえば、Lstが[a、[b、c、[d]]、e]の場合、deep-reverseは[e、[[d]、c、b]、a]を返します。

この練習に誰かが助けてくれますか?まず

element_reverse(List) -> 
    Flat = lists:flatten(List), 
    lists:reverse(Flat). 
+0

はあなたが何の助けが必要ですか? –

+0

あなたは今まで何をしようとしていますか? –

+0

私はその考えに従っています。まず、flatten関数を使用してリスト内のすべての要素を抽出します。次に、reverse関数を使用して逆のリストを作成します。現在の難しさは、逆リストの要素を入力リストの要素に置き換えることができないということです。 –

答えて

1

は、単純な逆関数は深い機能せず、次のようになりどのように見てみましょう。

パラメータが1つの関数では十分ではありません。アキュムレータが必要です。この値は、次の再帰的ステップに持ち越されます。アキュムレータは、最初は空のリストであり、再帰の各ステップでは、連続して埋められます。

simple_reverse(List) -> simple_reverse(List, []). 

だから、今、私たちはsimple_reverse(List, [])を呼び出すことができるように、2パラメータの関数を定義する必要があります。

simple_reverse([H|T], Accu) -> 
    simple_reverse(T, [H] ++ Accu); 

simple_reverse([], Accu) -> Accu. 

コンテンツ定義の最初の部分は、内容のあるリストを処理します。 [H|T]は、リストがあり、H(Head)がその最初の要素であり、T(テール)は残りのリストです。最初のパラメータとしてtailを使用してsimple_reverseと呼びます。最初にアキュムレータヘッドでヘッド値を累積します。

2番目の部分では、リストが空の場合を扱います。それが起こると、アキュムレータ(最初に蓄積されたすべての値)を返すことができます。

ここで何が起こったかを理解すると、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は、リスト自体([_|_])またはその他のもの(_)のいずれかです。再帰は、Hがリストである場合を除いて、実質的にsimple_reverseと同じです。それがリストであれば、再帰が実行されたときにを再度Hに呼び出す必要があります。

ここではいくつかのリンクは、構文を理解するために苦労していた場合、次のとおりです。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]を返すことができるように上記の関数を修正する方法を教えてもらえますか? –

関連する問題