Оптимизация уплотнения массивов

Допустим, у меня есть массив k = [1 2 0 0 5 4 0]

Я могу вычислить маску следующим образом m = k > 0 = [1 1 0 0 1 1 0]

Используя только маску m и следующие операции

  1. Shift left / right
  2. And/Or
  3. Add/Subtract/Multiply

я могу сжать k в следующее число [1 2 5 4]

Вот как я сейчас это делаю (псевдокод MATLAB):

function out = compact( in )
    d = in
    for i = 1:size(in, 2) %do (# of items in in) passes
        m = d > 0
        %shift left, pad w/ 0 on right
        ml = [m(2:end) 0] % shift
        dl = [d(2:end) 0] % shift

        %if the data originally has a gap, fill it in w/ the 
        %left shifted one
        use = (m == 0) & (ml == 1) %2 comparison  

        d = use .* dl + ~use .* d

        %zero out elements that have been moved to the left
        use_r = [0 use(1:end-1)]
        d = d .* ~use_r
    end

    out = d(1 : size(find(in > 0), 2)) %truncate the end
end

Интуиция

Каждую итерацию мы сдвигаем маску влево и сравниваем маски. Мы устанавливаем индекс для данных со сдвигом влево, если обнаруживаем, что после этого сдвига индекс, который изначально был void(mask[i] = 0), теперь valid(mask[i] = 1).

Вопрос

Приведенный выше алгоритм имеет O(N * (3 сдвига + 2 сравнения + AND + сложение + 3 умножения)). Есть ли способ повысить его эффективность?

22
задан ajmartin 5 December 2013 в 01:47
поделиться