关于map查找的问题,自定义结构体作为key

map查找的问题,自定义结构体作为key,为什么只重载“<”就可以了

重载了“<”就知道如何比较两个结构就能排列啦

只用<号也能判断相等啊:
if( (!(a<b) && !(b<a) )
   //ok,a==b
else
     //a!=b 

条款19:了解相等和等价的区别
STL充满了比较对象是否有同样的值。比如,当你用find来定位区间中第一个有特定值的对象的位置,find必须可以比较两个对象,看看一个的值是否与另一个相等。同样,当你尝试向set中插入一个新元素时,set::insert必须可以判断那个元素的值是否已经在set中了。

find算法和set的insert成员函数是很多必须判断两个值是否相同的函数的代表。但它们以不同的方式完成,find对“相同”的定义是相等,基于operator==。set::insert对“相同”的定义是等价,通常基于operator<。因为有定义不同,所以有可能一个定义规定了两个对象有相同的值而另一个定义判定它们没有。结果,如果你想有效使用STL,那么你必须明白相等和等价的区别。

问题:

不用“==”,只用“<”就可以判断两个对象是否相等。但是在楼上的文章中写到, map 中判断相等是给予“==”的。 又把握搞糊涂了。

解疑:

(1)成员函数map.find调用的是等价,也就是!c.key_comp()(x,   y)   &&   !c.key_comp()(y,   x),
算法find调用的是相等,如find(map.begin(), map.end(), a),调用的是对相等的operator ==

(2)find其实有两个,一个是算法的find,一个是map成员的find,而你调用的是成员的。成员的find是靠“<”,泛型算法的find靠的是"=="。

算法的find,类似find(map.begin(), map.end(), a)这种形式

你调用的find函数是Map的成员函数,类似map.find(a)这种形式,它只需要operator < 就够了

 

c++ STL容器 自定义类型的查找

leetcode的一道题,想使用map&amp;lt;A,B&amp;gt;class A{ public: bool operator &amp;lt;(const A &amp;amp; b)const { //需要实现,因为map要用到&amp;lt; return true; } };key 需要支持比较操作, 需要为A重载&quot;&amp;lt;&quot; 操作符....

 

在map的实现里面就是靠 对调operator<两边的操作数实现的。
set的源码如下:


       _Nodeptr _Lbound(const _K& _Kv) const
                {_Nodeptr _X = _Root();
                _Nodeptr _Y = _Head;
                while (_X != _Nil)
                        if (key_compare(_Key(_X), _Kv))  //就是operator<调用的地方
                                _X = _Right(_X);  //往右边子树走
                        else
                                _Y = _X, _X = _Left(_X); //记录父节点,往左边子树走
                return (_Y); }


       iterator find(const _K& _Kv)
                {iterator _P = lower_bound(_Kv); //这个_P就是_Lbound返回的_Y
                return (_P == end()
                        || key_compare(_Kv, _Key(_P._Mynode())) //把_P再和_Kv对调了比较一下
                                ? end() : _P); }

_Kv就是键值,注意_LBound里面,_Kv都是在后面来比较的,而find里面,最后还放在前面比较了一下,可以==就是靠两次<来完成比较的。

Map.find源码,成员函数map.find调用方式

iterator find(const key_type& _Keyval)
		{	// find an element in mutable sequence that matches _Keyval(在可变序列中查找与_Keyval匹配的元素)
		iterator _Where = lower_bound(_Keyval);
		return (_Where == end()
			|| _DEBUG_LT_PRED(this->_Getcomp(),
				_Keyval, this->_Key(_Where._Mynode()))
					? end() : _Where);
		}


	iterator lower_bound(const key_type& _Keyval)
		{	// find leftmost node not less than _Keyval in mutable tree(在可变树中找到不小于_Keyval的最左节点)
		return (iterator(_Lbound(_Keyval), this));
		}

_Nodeptr _Lbound(const key_type& _Keyval)
		{	// find leftmost node not less than _Keyval(找到不小于Keyval的最左节点)
		_Nodeptr _Pnode = _Root();
		_Nodeptr _Wherenode = this->_Myhead;	// end() if search fails

		while (!this->_Isnil(_Pnode))
			if (_DEBUG_LT_PRED(this->_Getcomp(), this->_Key(_Pnode), _Keyval))
				_Pnode = this->_Right(_Pnode);	// descend right subtree(往右边子树走)
			else
				{	// _Pnode not less than _Keyval, remember it(Pnode不小于Keyval,记住它)
				_Wherenode = _Pnode;
				_Pnode = this->_Left(_Pnode);	// descend left subtree(往左边子树走)
				}

		return (_Wherenode);	// return best remembered candidate
		}


 

stl map 使用结构体作为键,demo举例:

#include <iostream>
#include <map>
#include <string>
using namespace std;

struct package
{
    int id;
    string data;
    bool operator<(const package& tmp) const{
        if(this->id < tmp.id)
            return true;  //自定义排序规则
        return false;
    }
};

int main() {
    map<package,int> tmp;
    package a = {3,"a"};
    package b = {2,"b"};
    tmp.insert(make_pair(a, 0));
    tmp.insert(make_pair(b, 0));  //插入
    map<package, int>::iterator i;
    for(i = tmp.begin(); i != tmp.end(); i++)
        cout << i->first.id << " " << i->first.data << " " << i->second << endl;
}

【C++】自定义结构体作为map的key

文章参考链接:https://bbs.csdn.net/topics/190076742

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
unordered_map是C++标准库中的容器,用于存储键-值对并提供快速的查找功能。对于自定义结构体,可以使用unordered_map来存储该结构体作为键,并指定自定义的哈希函数和键的比较规则。 有三种常见的方式可以实现这个目标: 方法一:将自定义结构体中重载operator == 和自定义hash函数,并在unordered_map中传入自定义结构体类型和自定义hash函数类型,不传入第四个参数。 ```cpp #include <iostream> #include <unordered_map> #include <functional> class Person { public: int _age; Person(int age = -1) :_age(age) {} bool operator == (const Person& p) const { return _age == p._age; } }; struct PersonHash { public: size_t operator()(const Person& p) const { return std::hash<int>()(p._age); } }; int main() { std::unordered_map<Person, int, PersonHash> um; um.insert(std::make_pair<Person, int>(Person(1), 1)); um.insert(std::make_pair<Person, int>(Person(2), 1)); for (auto& e : um) { std::cout << e.first._age << " " << e.second << std::endl; } return 0; } ``` 方法二:自定义hash函数和自定义键的比较规则,并在unordered_map中传入自定义结构体类型、自定义hash函数类型和自定义键的比较规则类型。 ```cpp #include <iostream> #include <unordered_map> #include <functional> class Person { public: int _age; Person(int age = -1) :_age(age) {} }; struct PersonHash { public: size_t operator()(const Person& p) const { return std::hash<int>()(p._age); } }; struct PersonEqual { public: bool operator()(const Person& p1, const Person& p2) const { return p1._age == p2._age; } }; int main() { std::unordered_map<Person, int, PersonHash, PersonEqual> um; um.insert(std::make_pair<Person, int>(Person(1), 1)); um.insert(std::make_pair<Person, int>(Person(2), 1)); for (auto& e : um) { std::cout << e.first._age << " " << e.second << std::endl; } return 0; } ``` 方法三:传入自定义结构体类型,不重载operator == 和自定义hash函数。 ```cpp #include <iostream> #include <unordered_map> class Person { public: int _age; Person(int age = -1) :_age(age) {} }; int main() { std::unordered_map<Person, int> um; um.insert(std::make_pair<Person, int>(Person(1), 1)); um.insert(std::make_pair<Person, int>(Person(2), 1)); for (auto& e : um) { std::cout << e.first._age << " " << e.second << std::endl; } return 0; } ``` 以上是三种使用unordered_map存储自定义结构体的方法,具体使用哪种方式取决于你的需求和喜好。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值