2017-01-22 12 views
0

У меня есть одномерный массив Repa, который состоит из 0 и 1, и я хочу рассчитать его кодировку длины пробега. Например: поворот [0,0,1,1,1,0,0,0,1,0,1,1] into [2,3,3,1,1,2] или что-то подобное. (Я использую представление списка из-за удобочитаемости)Кодировка длины строки массива Repa

В идеале, мне бы хотелось, чтобы длина пробега 1 и игнорировались 0. So [0,0,1,1,1,0,0,0,1,0,1,1] becomes [3,1,2].

Я хотел бы получить результат (Repa).

Как это сделать, используя Repa? Я не могу использовать map или traverse, так как они дают мне только один элемент за раз. Я мог бы попробовать fold с каким-то специальным аккумулятором, но это не кажется идеальным, и я не знаю, что это даже возможно (из-за законов монады).

+0

Является ли ваш массив одномерным? Если нет: вы хотите кодирование для каждой строки или для одномерного представления n-dim вещи? – sdx23

+0

@ sdx23 Мой массив одномерный. – Valerie94

+0

Репа не создана для такого рода вещей. Вам лучше всего использовать что-нибудь еще ... Зачем вам нужна репа? – Alec

ответ

0

Я сейчас просто перебираю массив и возвращаю список, не используя никакой функции Repa. Я работаю над Boolean s вместо 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. Я прочитал все образцы из файла и преобразовал их в Booleans. 2. Я вызываю runLength для вычисления кодировки во время выполнения. 3. Я печатаю результат в stdout. Используя мою функцию, в среднем это занимает 0,013. Используя вашу функцию, в среднем это занимает 0.249s. С вашей функцией мне по-прежнему приходится извлекать длины выполнения для значений True из результата. – Valerie94