【问题标题】:Creating unordered map in C++ for counting the pairs在 C++ 中创建无序映射以计算对
【发布时间】:2022-01-04 17:07:51
【问题描述】:

假设我有一个数组1 2 1 2 3 4 2 1,我想将所有(arr[i], arr[i-1) 存储为arr[i] != arr[i-1] 作为一对在unordered_map 中用于计算这些对。
例如

(1, 2)  -> 2
(2, 3) -> 1
(3, 4) -> 1
(4, 2) -> 1
(2, 1) -> 1

所以我尝试的语法,

unordered_map<pair<int, int>,  int> umap;
int temp; 
cin>>temp;
arr[i]=temp;
for (int i=1; i< n; i++){
   cin>>temp;
   arr[i]=temp;
            
   umap[(arr[i-1], arr[i])]++;
}

接下来,我也尝试了正确的定义。

unordered_map<pair<int, int>,  int> umap;
cin>>temp;
arr[i]=temp;
for (int i=1; i< n; i++){
   cin>>temp;
   arr[i]=temp;
   pair<int, int> p(arr[i-1], arr[i]);
   umap[p]++;
}

谁能帮我找到正确的语法?

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    这种情况下的问题是std::unordered_map 需要一个可散列的键类型。 (它被实现为一个哈希图)

    但是std::hashstd::pair&lt;&gt; 没有重载,因此您的std::unordered_map 无法编译。


    使用普通的std::map

    您可以通过切换到只需要operator&lt; 的法线贴图来解决此问题,而is implemented by std::pair

    std::map<std::pair<int, int>,  int> umap;
    
    int values[] = {1, 2, 1, 2, 3, 4, 2, 1};
    for (int i=1; i< sizeof(values) / sizeof(int); i++) {
        umap[std::pair(values[i-1], values[i])]++;
    }
    

    godbolt example


    创建哈希函数

    或者如果你想保留 hashmap,你需要为你的 pair 提供一个散列函数,例如:

    struct pair_hash
    {
        template <class T, class U>
        std::size_t operator()(std::pair<T, U> const& pair) const {
            return std::hash<T>()(pair.first) ^ std::hash<U>()(pair.second);
        }
    };
    

    然后将其用于您的地图:

    std::unordered_map<std::pair<int, int>,  int, pair_hash> umap;
    
    int values[] = {1, 2, 1, 2, 3, 4, 2, 1};
    for (int i=1; i< sizeof(values) / sizeof(int); i++) {
        umap[std::pair(values[i-1], values[i])]++;
    }
    

    godbolt example

    警告:在这个例子中,这对中的两个哈希值只是被异或。一般来说,这不是一个很好的组合哈希的方法,您应该将其替换为更好的函数以供生产使用,例如this hash_combine function

    【讨论】:

      【解决方案2】:

      您不能只使用unordered_mappair,因为没有实现默认哈希。 但是,您可以使用map,它应该可以很好地满足您的目的,因为pair 确实实现了&lt;。 当您真正需要 unordered_map 时,请参阅 Why can't I compile an unordered_map with a pair as key?

      你可以用这样的花括号构造pair

      umap[{arr[i-1], arr[i]}]++;
      

      我认为是从 C++11 开始,但可能是 C++14 甚至 C++17

      【讨论】:

        猜你喜欢
        • 2017-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多