Let\'s say I have an array
k = [1 2 0 0 5 4 0]
I can compute a mask as follows
m = k > 0 = [1 1 0 0 1 1 0]
Using only the mask m and
Original code moves array element only one step at a time. This may be improved. It is possible to group array elements and shift them 2^k steps at once.
First part of this algorithm computes how many steps should each element be shifted. Second part moves elements - first by one step, then by 2, then 4, etc. This works correctly and elements are not intermixed because after each shift there is enough space to perform 2 times larger shift.
Matlab, code not tested:
function out = compact( in )
m = in <= 0
for i = 1:size(in, 2)-1
m = [0 m(1:end-1)]
s = s + m
end
d = in
shift = 1
for j = 1:ceil(log2(size(in, 2)))
s1 = rem(s, 2)
s = (s - s1) / 2
d = (d .* ~s1) + ([d(1+shift:end) zeros(1,shift)] .* [s1(1+shift:end) zeros(1,shift)])
shift = shift*2
end
out = d
end
The above algorithm's complexity is O(N * (1 shift + 1 add) + log(N) * (1 rem + 2 add + 3 mul + 2 shift)).