在 STL 中使用 unordered_map 存储键值对

Posted

技术标签:

【中文标题】在 STL 中使用 unordered_map 存储键值对【英文标题】:Using unordered_map to store key-value pairs in STL 【发布时间】:2018-08-06 00:16:32 【问题描述】:

我必须在我的程序中存储一些数据,如下所述。

数据是高维坐标和这些坐标中的点数。下面是一个简单的例子(坐标维度为 5):

  coordinate        # of points
(3, 5, 3, 5, 7)          6
(6, 8, 5, 8, 9)          4
(4, 8, 6, 7, 9)          3

请注意,即使我以 5 维为例,实际问题是 20 维。坐标始终是整数。

我想将此信息存储在某种数据结构中。我首先想到的是哈希表。我在 STL 中尝试了unordered_map。但无法弄清楚如何使用坐标作为unordered_map 中的键。定义为:

unordered_map<int[5], int> umap;

或者,

unordered_map<int[], int> umap;

给我一​​个编译错误。我做错了什么?

【问题讨论】:

“给我一个编译错误。” 你有没有读过编译器错误所说的内容?与我们分享知识怎么样?另外,请阅读:minimal reproducible example C 数组与其他类型的变量根本不同。例如,您不能直接分配给它们,也不能像您尝试做的那样将它们放入标准库容器中。尝试使用std::array 【参考方案1】:

unordered_map 需要知道如何散列您的坐标。此外,它需要一种比较相等坐标的方法。

您可以将坐标包裹在classstruct 中,并提供自定义operator == 来比较坐标点。然后你需要专门化std::hash 才能使用Point 结构作为unordered_map 中的键。虽然比较坐标是否相等非常简单,但您可以决定如何对坐标进行哈希处理。以下是您需要实施的概述:

#include <vector>
#include <unordered_map>
#include <cmath>

class Point

    std::vector<int> coordinates;

public:

    inline bool operator == (const std::vector<int>& _other)
    
        if (coordinates.size() != _other.size())
        
            return false;
        

        for (uint c = 0; c < coordinates.size(); ++c)
        
            if (coordinates[c] != _other[c])
            
                return false;
            
        
        return true;
    
;

namespace std

    template<>
    struct hash<Point>
    
        std::size_t operator() (const Point& _point) const noexcept
        
            std::size_t hash;

            // See https://www.boost.org/doc/libs/1_67_0/doc/html/hash/reference.html#boost.hash_combine
            // for an example of hash implementation for std::vector.
            // Using Boost just for this might be an overkill - you could use just the hash_combine code here.

            return hash;
        
    ;


int main()

    std::unordered_map<Point, int> points;

    // Use points...    

    return 0;

如果你知道你将拥有多少个坐标,你可以像这样命名它们

struct Point

    int x1;
    int x2;
    int x3;
    // ... 

您可以使用纯标题hashing library 我正是为此目的而编写的。您的里程可能会有所不同。

【讨论】:

我认为如果维度数已知,std::array 可能更适合在这里存储坐标。 @FeiXiang 我同意——无论是数组还是元组作为模板类的成员,都接受类型和 size_t 来表示元素的数量。使用std::vector的好处是可以在同一个容器中存储坐标数不同的点。【参考方案2】:

Hack 方式

我已经看到在编程比赛中使用它以方便使用。您可以将点集转换为字符串(连接每个坐标并用空格或任何其他特殊字符分隔它们),然后使用unordered_map&lt;string, int&gt;

unordered_map<string, int> map; int p[5] = 3, 5, 3, 5, 7;

string point = to_string(p[0]) + " " + to_string(p[1]) + " " to_string(p[2]) + " " to_string(p[3]) + " " to_string(p[4]);

map[point] = 6;

【讨论】:

以上是关于在 STL 中使用 unordered_map 存储键值对的主要内容,如果未能解决你的问题,请参考以下文章

STL: unordered_map 自定义键值使用

Leetcode-1 两数之和(STL, hashTable, unordered_map)

Leetcode-1 两数之和(STL, hashTable, unordered_map)

STL—unordered_set和unordered_map使用及源码剖析

(转载)STL map与Boost unordered_map的比较

C++ STL unordered_map详解