假设我有一个隔行扫描数据数组,例如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);
}
Run Code Online (Sandbox Code Playgroud)
遗憾的是,它不适用于不是2的大小的数组
编辑:无论如何,这个算法在更大的2的力量下失败,所以我想我再次在0
编辑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);
}
Run Code Online (Sandbox Code Playgroud)
编辑3我猜正确的术语是deinterleave,而不是deinterlace
vha*_*lac 11
这基本上是矩阵转置问题.你的阵列
[1 a]
[2 b]
[3 c]
[4 d]
Run Code Online (Sandbox Code Playgroud)
等价于 1, a, 2, b, 3, c, 4, d表示为向量(通过首先读取行).该矩阵的转置是:
[1 2 3 4]
[a b c d]
Run Code Online (Sandbox Code Playgroud)
这相当于1, 2, 3, 4, a, b, c, d.
有一个维基百科页面,处理一般情况下的就地矩阵转置.我想,非方矩阵的算法可以直接应用.
你可以使用慢速(不确定是否为O(n ^ 2)或更差,并且它是迟到的)算法.我们的想法是将子阵列从一个位置旋转到另一个i位置2*i.例如:
START: 1a2b3c4d5e6f
1(a2)... -> 1(2a)...
12(ab3)... -> 12(3ab)...
123(abc4)... -> 123(4abc)...
1234(abcd5)... -> 1234(5abcd)...
12345(abcde6)... -> 12345(6abcde)..
123456(abcdef) -> DONE
Run Code Online (Sandbox Code Playgroud)
数组的第一个成员是索引0.在步骤1,您选择子数组a[1:2],然后向右旋转(所有成员转到下一个位置,最后一个转到开始).下一步,选择a[2:4]并旋转它等.确保不旋转最后一个子阵列a[n/2:n].
最后一个选项,如果你不需要为性能(例如memcpy)进行批量操作,则提供一个访问器函数,并转换索引而不是移动任何字节.写这样的函数几乎是微不足道的:如果index小于max/2,则返回entry 2*index,否则返回entry 2*(index-max/2)+1.
| 归档时间: |
|
| 查看次数: |
2591 次 |
| 最近记录: |