假设我有一个交错的数据数组,例如1a2b3c4d5e,我想将其解开成一个看起来像12345abcde的数组,并且不需要使用临时缓冲区。最快的方法是什么?
目前我所拥有的是:
目前我所拥有的是:
template<typename T>
void deinterlace(T* arr, int length){
if(length<=1) return;
int i = 1;
for(i = 1; i*2<length; i++){
//swap i with i*2
T temp = arr[i];
arr[i] = arr[i*2];
arr[i*2] = temp;
}
deinterlace(arr+i, length-i);
}
很遗憾,这个算法无法处理大小不是2的幂次方的数组。
编辑:无论如何,在较大的2的幂次方时,此算法都会失败,所以我又回到了起点。
编辑2:我已经找到了一个nlogn的算法,只要有一个O(n)的数组旋转函数或者一个初始大小是2的幂次方,就可以使用。
它的工作原理如下:
1a2b3c4d5e6f7g,“块大小”= 1(最初)
将其拆分为每组块大小* 4的组 1a2b 3c4d 5e6f 7g
交换每组内部的2个块 12ab 34cd 56ef 7g
使用块大小=块大小* 2重复
12ab34cd 56ef7g(读作:56 ef 7 g)-> 1234abcd 567efg
1234abcd567efg -> 1234567abcdefg
template<typename T>
void deinterlace(T* arr, int length, int group_ct = 1){
if(group_ct*2 >= length) return;
for(int i = 0; i<length; i+=group_ct*4){
int rot_count = group_ct;
int i1 = i + group_ct;
int i2 = i+group_ct*4 - group_ct;
if(i2+group_ct > length){
i2 = i1 + (length-i1)/2+group_ct/2;
}
rotate(arr, i1, i2, group_ct);
}
deinterlace(arr, length, group_ct * 2);
}
编辑3:我猜正确的术语应该是去交错(deinterleave),而不是去隔行扫描(deinterlace)