【发布时间】:2011-10-15 19:55:13
【问题描述】:
假设我有一个交错数据数组,例如 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 的更大幂时都失败了,所以我想我又在 0 方格了
edit 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);
}
edit 3我猜正确的术语是去交错,而不是去交错
【问题讨论】:
-
一般来说,这不是一个简单的任务。这在 DSP 算法中很常见,并且有很多关于如何有效地做到这一点的研究。也许这种情况有一个简单有效的解决方案。我会等待有人证明我错了。
-
是的,它用于音频引擎。我想我可以将初始数组填充到 2 的幂,但是这样我就浪费了空间,还不如使用一个临时数组。
-
@GlaielGamer 填充到最近的幂可能比将数组加倍小很多,具体取决于块的大小(取 60 或 4000)。
-
你提前知道数组的大小吗?它是常数,还是少数常数之一?
-
是的,但是填充的版本将永远保留在内存中,而临时文件可以在使用完成后被释放。