2017-05-12 17 views
0

ハスケルのリストを逆にする関数が組み込まれていますが、ハスケルを練習するために自分の小さな関数を書こうとしています。私は悲しいかなか働いていない次のコードを考えました。あなたは私が間違っていたことを教えてもらえますか?ハスケルで逆関数を書くには

rev :: [Int] -> [Int] 
    rev [] = [] 
    rev [x] = last [x] : rev init [x] 
+0

'[x]'は一つの要素( 'x'という名前)を含むリストです。 'last [x]'は 'x'だけで、' init [x] 'は' [] 'です。 'last [x]:rev init [x]'は 'x:rev []'です。これは 'x:[]'です。これは '[x]'です。最後の行は 'rev [x] = [x]'と同じです。しかし、あなたの主な問題は、複数の要素を持つリストの場合がないということです。 – sepp2k

答えて

2

あなたはほとんどそれを持っていました。

rev :: [Int] -> [Int] 
rev [] = [] 
rev x = last x : rev (init x) 

説明:あなたはX

PSを直接操作したいのに対し、[X]は、Xを含むリストでした。ここにはdocumentation for Data.Listがあります。そしてimport Data.List

+0

これは私が探していたものです!どうもありがとう! –

+0

あなたは大歓迎です!あなたの質問にうまく答えていると感じたら、答えを受け入れることを忘れないでください(緑色のチェックマークをクリックしてください)。 – vikingsteve

+0

Downvoter、相談する? – vikingsteve

2

ウェルに覚えて、あなたはこのような何かを行うことができます:

rev :: [Int] -> [Int] 
rev [] = [] 
rev (x:l) = (rev l) ++ [x] 

3行目は、リストから最初の要素を取り、その後にのみ、その要素を含むリストを作成します。これは再帰呼び出しrev l呼び出しの結果に追加されます。

2

あなたが効率的にそれをしたい場合は、私はあなたがアキュムレータを使用することをお勧めしたい:

rev :: [a] -> [a] 
rev xs = go xs [] 
    where 
    go :: [a] -> [a] -> [a] 
    go []  ys = ys 
    go (x:xs) ys = go xs (x:ys) 

機能goは、各ステップで、最初のリストxsから一つの要素を削除し、第二に、それを付加しますリストysこれは、スタックからポップし、別のスタックにプッシュすることに似ています。これは、順序を逆転させます。

各再帰呼び出しで一定の時間しか使用しないため、O(n)の複雑さが得られます(nはリストの長さです)。

代わりに、それぞれの再帰呼び出しでlastを使用するか、... ++ [x]を追加すると、各呼び出しにO(n)、したがって全体としてO(n^2)が支払われます。