c++之复杂类型作为unordered_map的键值

unordered_map & unordered_set

我们知道c++中有unordered_map和unordered_set这两个数据结构,其内部实现是哈希表,这就要求作为键值的类型必须是可哈希的,比如常见的数据类型int、string等。但在很多应用中我们可能需要用到比较复杂的类型作为键值,比如vector<int>、pair<int,int>,乃至自定义的类,这时候就需要手动编写两个类作为创建该数据结构对象时的参数,具体我们来看一下。

现在我想让pair<int,int>作为unorderd_map的键值,需要编写两个类,每个类中分别包含一个函数,第一个类中的函数叫做哈希函数,将某一个pair<int,int>的对象哈希了,返回其哈希值;第二个叫做相等函数,用于判断两个pair<int,int>对象是否相等,意在解决冲突。

ps:类与结构其实是类似的,可以相互替代使用

struct Hashfunc {
    
    
    size_t operator() (const pair<int,int>& key) const{
    
    
        return hash<int>()(key.first) ^ hash<int>()(key.second);
    }
};
struct Equalfunc {
    
    
    bool operator() (const pair<int,int>& a, const pair<int,int>& b) const{
    
    
        return a.first == b.first && a.second == b.second;
    }
};

这两个类的具体实现完全由你自己决定,只是需要注意一点,因为这两个类是作为参数传递给unordered_map的,所以定义时需要满足某些规则,比如Hashfunc的返回值是size_t,再比如Equalfunc里的判断函数必须添加const字段。

编写完以上两个类,将它们传给要创建的数据结构对象,然后就可以使用啦。

unordered_map<pair<int,int>, int, Hashfunc, Equalfunc> mp;

map & set

上面讲的是unordered_map和unordered_set的应用,如果是map和set呢?我们知道map和set内部的实现是树,既然运用到二叉搜索树就必须得有比较两个元素大小的方法,上面提到的pair<int,int>和vector<int>,好像map自动提供给其比较的方法了,所以可以直接作为键值使用,不用自己定义类。

什么时候需要自己定义类呢?答案是使用自定义类作为键值的时候。与上面类似,我们现在定义一个类,类中的函数我们同样给它一个名字,就叫小于函数吧,这个函数用来判断两个元素值的大小。
如下:

class T {
    
    
	public:
	int a,b;
	T(int c, int d) {
    
    
		a = c;
		b = d;
	}
};
struct Tless {
    
    
	bool operator() (const T& a, const T& b) {
    
    
		return a.a < b.a;
	}
};
map<T, int, tless> mp2;

猜你喜欢

转载自blog.csdn.net/weixin_43867940/article/details/105775739