[英]What is the best way traversing an unordered_map with a starting from a random element in C++?
我有一個包含“n”個元素的 unordered_map。 它有一些符合條件的元素。 我想寫一個 function 這樣每次都會選擇一個隨機的合格元素。 能否在以下時間復雜度內實現? 最佳情況:O(1) 平均情況:O(1) 最壞情況:O(n)
參考 - 在 c++ 中檢索 std::map 的隨機密鑰元素,我想出了以下解決方案。
#include <iostream>
#include <unordered_map>
#include <random>
using namespace std;
void select_random_best(const std::unordered_map<std::string, int>& umap, const int random_start)
{
cout << "Selected random number " << random_start << endl;
auto it = umap.begin();
std::advance(it, random_start);
for(int i = 0; i < umap.size(); i++, it++) {
if(it == umap.end())
it = umap.begin();
// Check if the selected element satisfies the eligibility criteria.
// For the sake of simplicity, I am taking the following example.
if(it->second % 3 == 0) {
cout << it->first << ", " <<
it->second << endl;
return;
}
// Element not found continue searching
}
}
int main()
{
srand(time(0));
unordered_map<string, int> umap;
// inserting values by using [] operator
umap["a"] = 6;
umap["b"] = 3;
umap["f"] = 9;
umap["c"] = 2;
umap["d"] = 1;
umap["e"] = 3;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> distrib(0, umap.size() - 1);
const int random_start = distrib(gen);
select_random_best(umap, distrib(gen));
// another iteration
select_random_best(umap, distrib(gen));
cout << "Full list :" << endl;
// Traversing an unordered map
for (auto x : umap)
cout << x.first << ", " <<
x.second << "\t";
}
有人可以建議在這里使用std::advance()
是否會導致 O(1) 的平均用例時間復雜度? 或者有更好的方法嗎?
std::unordered_map
具有前向迭代器,不允許隨機訪問。 請參閱容器文檔頁面上的iterator
。
假設所有元素都符合條件, std::advance()
將平均為 go 到size/2
元素。 因為你只接受符合條件的元素,所以你將 go 通過不止於此。 如果您知道符合條件的概率,則可以估計搜索到的平均元素。
要在std::advance()
步驟中實現 O(1),您必須使用具有隨機訪問迭代器的數據類型,例如std::vector
。 然而,下一步並不具有恆定的復雜性。 在最壞的情況下,您將 go 遍歷所有不符合條件的元素(不考慮如果沒有符合條件的元素可能會無限循環)。 所以這種方法整體上仍然是 O(n)。
為了獲得最佳性能,您需要兩個列表:僅包含符合條件的元素的std::vector
,用於查找隨機元素,以及用於其他內容的std::unordered_map
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.