有时候我们会有用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为例的,此外使用到相关数据结构的时候,只要底层涉及到了红黑树(红黑树会排序),就需要注意这一问题。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)