map存储自定义类型数据

map存储自定义类型数据,第1张

问题引出:

有时候我们会有用map存储自定义类型的需求
首先看个map存储自定义类型数据失败的例子顺便分析一下原因
这里自定义了一个结构体对象Test

struct Test
{
public:
	Test(int a, int p, string s) :m_a(a), m_p(p), m_s(s)
	{}
	int m_a;
	int m_p;
	string m_s;
};
void main() {
	Test t1(1, 4,"苹果");
	Test t2(1, 10,"草莓");
	Test t3(1, 30,"樱桃");

	map<Test,int> s;
	s.insert(pair<Test, int>(t1, 1));
	s.insert(pair<Test, int>(t2, 2));
	s.insert(pair<Test, int>(t3, 3));
	for (auto& e : s) {
		cout << e.first.m_a<< " : " << e.first.m_p << " : " << e.first.m_s << endl;
	}

}

上面代码是无法运行通过的,主要是因为map和set底层结构为红黑树,红黑树会对其元素进行排序。
已有的数据类型,红黑树底层已经规定了其排序方法,一般默认从小到大排序,也通过参数设置为从大到小排序;
但是自定义类型的排序规则底层肯定没有实现,需要我们手动实现一下。

方法一:
template < class Key,                                     // map::key_type
           class T,                                       // map::mapped_type
           class Compare = less<Key>,                     // map::key_compare
           class Alloc = allocator<pair<const Key,T> >    // map::allocator_type
           > class map;

如上所示,map的定义中有第三个参数class Compare = less,,这个参数是系统默认的大小比较方法–>是一个仿函数,那么我们就可以自己设计这个仿函数并显示调用即可。

struct Test
{
public:
	Test(int a, int p, string s) :m_a(a), m_p(p), m_s(s)
	{}
	int m_a;
	int m_p;
	string m_s;
};
class myCompare
{
public:
	bool operator()(const Test& t1, const Test& t2) const
	{
		return t1.m_p > t2.m_p;  //这里用m_p进行大小比较
	}
};
void main() {
	Test t1(1, 4,"苹果");
	Test t2(1, 10,"草莓");
	Test t3(1, 30,"樱桃");

	map<Test,int, myCompare> s;
	s.insert(pair<Test, int>(t1, 1));
	s.insert(pair<Test, int>(t2, 2));
	s.insert(pair<Test, int>(t3, 3));
	for (auto& e : s) 
		cout << e.first.m_a<< " : " << e.first.m_p << " : " << e.first.m_s << endl;
}


这样代码即可正常运行。

方法二:

此外也可以在自定义类型中重载一下 < 或 > 号的比较方式。
eg:

struct Test
{
public:
	Test(int a, int p, string s) :m_a(a), m_p(p), m_s(s)
	{}

	eg:根据m_p大小进行排序
	//bool operator < (const Test& t) const
	//{
	//	return m_p < t.m_p;
	//}
	//eg:根据m_s的字母顺序进行排序
	bool operator < (const Test& t) const
	{
		return (strcmp(m_s.c_str(), t.m_s.c_str())) < 0;
	}

	bool operator > (const Test& t) const
	{
		return m_p > t.m_p;
	}


	int m_a;
	int m_p;
	string m_s;
};

class myCompare
{
public:
	bool operator()(const Test& t1, const Test& t2) const
	{
		return t1.m_p > t2.m_p;
	}
};

void main() {
	Test t1(1, 4,"苹果");
	Test t2(1, 10,"草莓");
	Test t3(1, 30,"樱桃");

	map<Test,int> s;
	//map> s;
	s.insert(pair<Test, int>(t1, 1));
	s.insert(pair<Test, int>(t2, 2));
	s.insert(pair<Test, int>(t3, 3));
	for (auto& e : s) 
		cout << e.first.m_a<< " : " << e.first.m_p << " : " << e.first.m_s << endl;

}

这里我在Test类中重载了小于号的比较方式,使其按照m_s的字符串大小进行排序

上面是以map为例的,此外使用到相关数据结构的时候,只要底层涉及到了红黑树(红黑树会排序),就需要注意这一问题。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/875070.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存