簡體   English   中英

從 C++ 中的隨機元素開始遍歷 unordered_map 的最佳方法是什么?

[英]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.

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