簡體   English   中英

關於迭代器順序的c ++ std :: map問題

[英]c++ std::map question about iterator order

我是一個嘗試使用地圖的C ++新手,所以我可以獲得find()方法的恆定時間查找。

問題是,當我使用迭代器遍歷地圖中的元素時,元素的顯示順序與它們放置在地圖中的順序不同。

如果不維護另一個數據結構,是否有一種方法可以實現按順序迭代,同時仍然保持恆定的時間查找能力?

請告訴我。

謝謝,jbu

編輯:感謝讓我知道map :: find()不是常數時間。

如果不維護另一個數據結構,是否有一種方法可以實現按順序迭代,同時仍然保持恆定的時間查找能力?

不,那是不可能的。 為了獲得有效的查找,容器將需要以有效查找的方式對內容進行排序。 對於std :: map,這將是某種類型的排序順序; 對於std :: unordered_map,這將是一個基於密鑰哈希的順序。

在任何一種情況下,訂單都將與添加訂單的順序不同。

首先, std::map保證O(log n)查找時間。 你可能會想到std::tr1::unordered_map 但是,根據定義,犧牲任何順序來獲得恆定時間查找。

你必須花一些時間在它上面,但我認為你可以抨擊boost::multi_index_container來做你想做的事情。

如何使用原始順序中的鍵的vector和快速訪問數據的map

像這樣的東西:

vector<string> keys;
map<string, Data*> values;

// obtaining values
...
keys.push_back("key-01");
values["key-01"] = new Data(...);
keys.push_back("key-02");
values["key-02"] = new Data(...);
...

// iterating over values in original order
vector<string>::const_iterator it;
for (it = keys.begin(); it != keys.end(); it++) {
    Data* value = values[*it];
}

當應用於鍵時,項目按operator< (默認情況下)排序。

PS。 std :: map不保證恆定時間查找。
它保證了O(ln(n))的最大復雜度

我真的要......向后走。

如果要保留插入元素的順序,或者通常要控制順序,則需要一個您將控制的序列:

  • std::vector (是的還有其他的,但默認使用這個)

您可以使用std::find算法(來自<algorithm> )在向量中搜索特定值: std::find(vec.begin(), vec.end(), value);

哦,是的,它具有線性復雜度O(N) ,但對於小型集合,它應該無關緊要。

否則,您可以按照建議開始查看Boost.MultiIndex ,但對於初學者,您可能會有點掙扎。

所以,暫時推卸復雜性問題,並提出一些有效的方法。 當您更熟悉該語言時,您會擔心速度。

首先, std::map不是常量時間查找。 它是O(log n)。 我以為我應該這樣做。

無論如何,如果要使用不同的順序,則必須指定自己的比較函數。 沒有可以按插入時間排序的內置比較函數,但是,如果對象包含時間戳字段,則可以安排在插入時設置時間戳,並使用按時間戳比較。

地圖不是用於按某種順序放置元素 - 使用向量。

如果你想在地圖中找到某些東西,你應該使用[操作員]按鍵“搜索”

如果您同時需要:迭代和按鍵搜索,請參閱此主題

是的,您可以創建這樣的數據結構,但不使用標准庫...原因是標准容器可以嵌套但不能混合。

實現例如地圖數據結構沒有問題,其中所有節點也按照插入順序處於雙向鏈表中,或者例如所有節點都在數組中的地圖。 在我看來,這些結構中的一個可能是你正在尋找的(取決於你喜歡哪種操作快),但是使用標准容器構建它們都不是很容易,因為每個標准容器( vectorlistset , ...)希望成為訪問包含元素的唯一方法。

例如,我發現在許多情況下有用的節點同時存在於多個雙向鏈表中,但你不能使用std::list來做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM