我需要一個非常快速的算法來完成以下任務。我已經實現了幾種完成它的算法,但它們對於我所需要的性能來說太慢了。它應該足夠快,可以在現代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