map存储自定义类型数据

问题引出:

有时候我们会有用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<Test, int,greater<>> 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为例的,此外使用到相关数据结构的时候,只要底层涉及到了红黑树(红黑树会排序),就需要注意这一问题。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值