我需要一个非常快速的算法来完成以下任务。我已经实现了几种完成它的算法,但它们对于我所需要的性能来说太慢了。它应该足够快,可以在现代CPU上运行至少10万次。它将用C++实现。帮助合并矢量的算法
我正在使用跨度/范围,一个结构有一个开始和一个结束坐标。
我有两个跨度的向量(动态数组),我需要合并它们。一个矢量是src,另一个是dst。矢量按跨度起点坐标排序,跨度在一个矢量内不重叠。
src向量中的跨度必须与dst向量中的跨度合并,使得生成的向量仍然排序并且没有重叠。 IE浏览器。如果在合并期间检测到重叠,则将两个跨度合并为一个。 (合并两个跨度只是改变结构中的坐标的问题。)
现在,还有一个catch,src向量中的跨度必须在合并期间“扩大”。这意味着一个常量将被添加到开始,另一个(更大的)常量将被添加到src中每个跨度的结束坐标。这意味着src跨度扩大后可能会重叠。
我到目前为止所做的是,它不能完全就地完成,需要某种临时存储。我认为在src和dst总结的元素数量的线性时间内应该是可行的。
任何临时存储都可能在算法的多次运行之间共享。
我曾尝试这两种主要方法,其是太慢,有:
追加的src到dst的所有元素,它追加之前加宽每个元素。然后运行就地排序。最后,使用“read”和“write”指针遍历结果向量,读指针在写指针前面运行,并在跨越时合并跨度。当所有元素都被合并(读指针到达结尾)时,dst被截断。
创建临时工作向量。通过反复从src或dst中选择下一个元素并合并到工作向量中,如上所述进行天真合并。完成后,将工作向量复制到dst,替换它。
第一种方法具有排序为O((M + N)*日志(M + N)),而不是O(M + N),并具有一定程度的开销的问题。这也意味着dst矢量必须增长得比实际需要的大得多。
第二个问题是大量复制和重新分配/释放内存的主要问题。
如果您认为需要,可以更改用于存储/管理跨度/矢量的数据结构。
更新:忘了说数据集有多大。最常见的情况是在任何一个向量中有4到30个元素,并且dst是空的,或者src和dst中跨度之间有大量重叠。
100k实际上可能是一个下冲,我还没有真正计算的数字。当我说“现代”的CPU时,我实际上在想“5年前的东西”,Athlon XP 3000+并不是不切实际的目标。 – jfs 2008-09-18 02:38:24