2009-10-20 38 views
14

我有一些數據與整數索引。我持續生成需要添加到我擁有的數據集合中的新數據,並按照該索引進行排序,同時我想輕鬆地開始數據並遍歷數據。這聽起來像std :: multimap就是我所需要的。stl的multimap如何插入尊重排序?

但是,我還需要將具有相同索引的數據按其插入的順序保存,在這種情況下,這意味着當我迭代數據時,我會在較晚的數據之前獲得較早的數據。

是否multimap做到這一點?

我還沒有找到任何保證,情況確實如此。在sgi手冊中,我沒有看到任何提及。我在gcc 4.3.4實現上嘗試了它,並且它對於一些有限的測試用例似乎是正確的,但是當然我想知道標準是否需要這個,我可以依賴這個事實。

編輯:爲了更清楚地回答一些答案,我希望數據首先按(非唯一)索引排序,其次按插入時間排序。我曾希望第二部分可以通過multimap免費獲得,但似乎沒有。

回答

8

除非我遺漏了某些東西,否則標準不提供任何此類擔保。

最明顯的解決方法是將序列號作爲輔助鍵。例如,在你的類中包含一個static unsigned long,並且每次創建一個要插入到multimap中的對象時,都將其當前值放入對象中,然後增加它。在您的對象的比較函數中,如果您當前用作關鍵字的數據相等,則使用該計數器作爲排序的決定因素。請注意,在這種情況下,每個鍵都是唯一的,因此您可以使用地圖而不是多地圖。

1

不,它不會。如果你想要的話,你應該使用一個「序列容器」像一個向量。例如,你可以使用std :: pairs加載一個向量?

1

這聽起來像多重映射是你所需要的...

但是,我也必須保持在其被插入 順序與 相同的索引數據,在這種情況下 意義當我通過 迭代我得到的數據之前的數據 之後的數據。

它將按照索引的順序排列。如果隨着時間的推移,索引隨着您插入更多項目而增加,那麼由於索引的性質,「較早」的數據將首先出現。

否則,沒有。你可以保留兩個multimaps到相同的數據。一個保持指數的順序,另一方面爲了插入時間:

std::multimap<index, T*> orderedByIndex; 
std::multimap<time, T*> orderedByInsertionTime; 

給你遍歷地圖左右逢源的能力。

編輯我讀這意味着你有時需要按指數迭代或有時迭代插入時間,但如果你的意思是第一個索引,然後插入時間,請參閱上面的答案。)

4

升壓multi_index支持您正在嘗試執行的操作,如果您不想採用Jerry Coffin給出的解決方法。

+0

示例如何? – Hermes 2014-07-08 11:38:20

2

如果我找到了你的話 - 你需要按某個鍵排序的數據。每當用相同的鍵插入2件東西時,您需要按照插入的順序檢索它們。

如果是這樣,那麼你必須看看你的multimap的實現。根據它如何處理使用相同密鑰的多次插入的情況,它可能有或沒有這種保證。我猜這個標準不提供這種保證,因爲它會限制一個非常特殊的情況。

另一種方法是去一個地圖(而不是多),並創建一個複合鍵。密鑰由你選擇的普通密鑰和一個增加的計數器組成。相比之下,使用相同的密鑰,插入號碼使密鑰具有唯一性。這樣你強制獨特的按鍵和順序在相同的「正常」鍵(我希望這是可以理解的)。

我猜最後一種方法是最容易實現的。


選項:(不推薦)

您可以隨時與此擔保自制的數據結構。我會選擇一個帶有矢量的Tree(紅黑或AVL)來保存插入的數據。在迭代中,你必須找到節點,去向量並迭代它的內容。每當你完成矢量,你就繼續下一個節點。

31

看來新標準(C++ 11)改變了這種:

其鍵比較當量是插入的順序和不改變的鍵 - 值對的順序。 [cppreference]

修改標準庫是C++ 11兼容的,我猶豫,雖然使用它,因爲這似乎是一個細節很容易被忽視,它是那種細節是否會默默地導致錯誤您的編譯器庫無法正確實現。

+3

嗯,這不像你在執行過程中無法檢查它。 – 2013-01-06 14:54:01