4

私はHaskellが初めてです。入力としてリストを指定すると、リストの各要素を k 回複製するプログラムを作成しようとしています。ここで、k= リスト内の要素の位置です。

例えばreplic[5,6,7]、与え[[5],[6,6],[7,7,7]]ます。

別の条件は、ソリューションがmap関数を使用する必要があることです。

今まで私が書いたコードは次のとおりです。

replic [] = [] 
replic (x:xs) =  map (replicate 2 ) [x] ++ replic xs 

複製には入力パラメーターがあるため、これはすべての要素を 2 回複製します2

私が必要とするのは、連続呼び出しのようにreplicate関数に入力を与えることです。1 ,2 ,3だからカウンターが欲しい。そこでカウンターを使用したり、要素の位置を取得するために何か他のことをしたりするにはどうすればよいですか?

4

3 に答える 3

8

Satvik を拡張すると、表記法

[1..]

カウントアップする数の無限のリストを提供します。

関数zipAssociates を使用すると、2 つのリストをタプルのリストにマージできます。

zip :: [a] -> [b] -> [(a,b)]

例えば

> zip [1..] [5,6,7] 
[(1,5),(2,6),(3,7)]

このコードは、リスト内の各値をリスト内の位置に関連付けます

replicate :: Int -> a -> [a]

値を任意の回数繰り返します。これら 2 つのコンポーネントがあれば、単純な関数を設計できます。

replic xs = map (\(a,b) -> replicate a b) (zip [1..] xs)

私はポイントフリーと書きます

replic :: [a] -> [[a]]
replic = map (uncurry replicate) . zip [1..]

これはまさにあなたが望むことをします

> replic [5,6,7]
[[5],[6,6],[7,7,7]]
于 2012-10-31T05:08:54.763 に答える
3

これを行うには多くの方法があります

これは、あなたがやろうとしたことに似た解決策です。リストをリストで圧縮すると[1..]、必要なカウンターが得られます。

replic = repl . zip [1..]

repl [] = []
repl ((x,y):xs)  = (replicate x y) : (repl xs)

ちょうど使用する別のソリューションmap

replic = map f . zip [1..]
    where
        f (c,l) = replicate c l

使用する考えが気に入らない場合は、使用zipすることもできますmapAccumL

import Data.List

replic = snd . mapAccumL f 1
    where
        f a v = (a+1,replicate a v)
于 2012-10-31T04:56:34.763 に答える
1

通常、次のように記述します。

replic = zipWith replicate [1..]

zipWithこれで、次を使用して自分で作成できますmap

zipWith' f xs ys = map (uncurry f) $ zip xs ys

必ずしもインデックスが必要ではないことに注意してください。

import Data.List

replic xs = reverse $ transpose (tail $ inits $ reverse xs)

map明示的な再帰を使用すると、次のようなことができます。

replic = f . map return where
  f [] = []
  f (x:xs) = x : f (map (\(x:xs) -> x:x:xs) xs)
于 2012-10-31T09:57:17.633 に答える