2017-01-22 7 views
0

0と1からなる1次元のRepa配列があり、そのランレングスエンコーディングを計算したいと思います。 例:[0,0,1,1,1,0,0,0,1,0,1,1] into [2,3,3,1,1,2]などと似ています。 (私は可読性のためにリスト表現を使用しています)Repa配列のランレングス符号化

理想的には、私は1のランレングスを望み、0を無視します。 だから[0,0,1,1,1,0,0,0,1,0,1,1] becomes [3,1,2]

私は結果が(Repa)アレイであることを望みます。

Repaを使ってどうすればいいですか? mapまたはtraverseは、一度に1つの要素しか与えられないため、使用できません。私はfoldアキュムレータのいくつかの特別な種類としようとすることができますが、それは理想的ではないようだと私はそれも(モナドの法律のため)可能ですそれを知らない。

+0

アレイは一次元ですか?そうでない場合:各行のエンコーディング、またはn次元のものの一次元表現のエンコードを行いますか? – sdx23

+0

@ sdx23私の配列は1次元です。 – Valerie94

+0

Repaはこの種のものには作られていません。あなたは何か他のものを使うのが良いでしょう...なぜあなたはレパを必要としますか? – Alec

答えて

0

私は現在、Repa関数を使用せずに配列を繰り返し、リストを返すだけです。私はBooleanの1と0の代わりに作業していますが、アルゴリズムは同じです。その後、このリストをRepaアレイに変換しています。

runLength :: Array U DIM1 Bool -> [Length] 
runLength arr = go ([], 0, False) 0 arr 
    where 
    Z :. n = extent arr 
    go :: Accumulator -> Int -> Array U DIM1 Bool -> [Length] 
    go [email protected](xs, c, b) !i !arr | i == n = if c > 0 then c:xs else xs 
           | otherwise = 
           if unsafeIndex arr (Z :. i) 
           then if b 
             then go (xs, c+1, b) (i+1) arr 
             else go (xs, 1, True) (i+1) arr 
           else if b 
             then go (c:xs, 0, False) (i+1) arr 
             else go (xs, 0, False) (i+1) arr 
+0

これはもっと一般的な 'map(length &&& head)とどのように比較されるのだろうか。グループ。 toList' – Cirdec

+1

@Cirdecセットアップは以下の通りです。1.ファイルからすべてのサンプルを読み込み、ブーリアンに変換します。 2. runLengthを呼び出して、ランレングス符号化を計算します。 3.結果を標準出力に出力します。 私の関数を使うと平均で0.013秒かかります。あなたの関数を使うと、これは平均して0.249秒かかる。あなたの関数では、結果からTrue値のランレングスを抽出する必要があります。 – Valerie94

関連する問題