2

リストを受け取る関数があり、リストに2つの同一の連続した数字があり、リストの他の場所に数字xがある場合、それは同等であり、xを0に変更し、リストを返します。

twoAdjThenThirdZero (x:y:xs) = [if x == y && x `elem` xs then 0 else x | x <- xs]

何らかの理由で、実行しようとするたびにリストの最初の 2 つの要素が省略されています。

*Main> twoAdjThenThirdZero [2,3,4,1,2,0,2,3,3]

[4,1,2,0,2,0,0]

また、上記のケースは、私が望むこととは逆のことをしています。リストの最後にある 2 つの 3 を保持し、2 番目の要素であるその 3 を 0 にしたいのですが、それが逆になりました。

*Main> twoAdjThenThirdZero [2,2,3,1,2,4]

[3,1,0,4]

これがなぜなのか誰か知っていますか?前もって感謝します!

4

2 に答える 2

2

これを試して:

adjToZero = adjToZero' (allDoubles xs) 

adjToZero' ds [] = []
adjToZero' ds [x] = [x]
adjToZero' ds (x:y:xs) = if (x/=y) && (x `elem` ds) then 0:(adjToZero' ds (y:xs))
                                                    else x:(adjToZero' ds (y:xs))

allDoubles [] = []
allDoubles (x:y:xs) = if (x==y) then x:(allDoubles xs)
                                else allDoubles (y:xs)

例:

> adjToZero [1,2,1,1]
[0,2,1,1]
于 2012-10-07T20:27:51.340 に答える
1

ここには複数の問題があります。関数宣言でパラメーター リストを分解することから始めますtwoAdjThenThirdZero (x:y:xs)。ステップごとに x と y を取得し続けたい場合は、再帰する必要があります。代わりに、リスト内包表記と x の複製を使用するように切り替えます。リスト内包表記では、関数パラメーターの最初の 2 つ (x と y) を除くすべての要素である xs を調べます。

リスト内包表記を声に出して読めばわかると思います。

「x が y に等しく、x が xs の要素である場合、xs 内のすべての x について、それ以外の場合はゼロ」。しかし、x+y+xs のすべての x に対して実行したい! また、関数の引数の分解とリスト内包表記の変数の両方で、「x」という名前を 2 つの方法で使用しています。

編集:

今、私はあなたの意味がわかります。明示的な再帰を既に持っているものに追加するだけです。

twoAdjThenThirdZero [] = []
twoAdjThenThirdZero [x] = [x]
twoAdjThenThirdZero (x:y:xs) 
  | x == y && x `elem` xs = x : y : twoAdjThenThirdZero [if z == x then 0 else z | z <- xs]
  | otherwise             = x : twoAdjThenThirdZero (y:xs)

理解していただければ幸いです。理解できない場合は、さらに説明します。

編集:

Phynfo は、私が書いていたものを少し単純化したバージョンを投稿しました!

于 2012-10-07T19:37:59.003 に答える