我的结构如下:
struct MyStruct
{
char *name;
map<char*,char*> mymap;//assume that this map insert data in increasing order
};
我有另一张地图:
map<MyStruct,int,Compare> mTest;
//compare function for less then operator
struct Compare
: public std::binary_function<MyStruct, MyStruct, bool>
{
bool operator()(const MyStruct &a, const MyStruct&b)
{
if(strcmp(a.name,b.name)< 0)
return true;
else if(strcmp(a.name,b.name)==0)
{
//How should I compare map `mymap` ??
}
return false;
}
}
那么我应该如何为mymap
撰写比较?
这基本上是我想要的:
如果
,两张地图相同名称相等
他们的地图大小相等
那么地图的内容应该是相同的,即它们的键和值。
答案 0 :(得分:1)
你对char*
的使用坦率地说是可怕的并且已经过时了。使用std::string
,您的班级将成为:
struct MyStruct
{
std::string name;
map<std::string, std::string> mymap;
};
现在,对于地图,您需要提供 less-than 运算符,例如:
struct MyStruct
{
std::string name;
map<std::string, std::string> mymap;
friend bool operator<(MyStruct const& lhs, MyStruct const& rhs)
{
// Now the comparison is easier - use the defaults!
if (lhs.name < rhs.name)
return true;
return lhs.mymap < rhs.mymap; // this does a lexicographical comparison of all values.
}
};
然后您的结构图变为:
std::map<MyStruct, int> mTest;
无需繁琐的代码。
编辑:只是注意到了您的更新,您可以为MyStruct
实施其他运算符,并按照我上面所做的那样通过调用name
和mymap
的逻辑运算符来编写它们,你不需要自己实施任何自定义黑客攻击。
答案 1 :(得分:1)
您可以通过多种方式订购地图。必须考虑三件事:地图的大小,键和值。由于地图本身已经按键排序,因此比较键之后的值是很自然的。因此,给定两个相同大小的地图,只有键才重要。我将使用整数键和值来获得更简单的示例:
map1: 1->42 map2: 5->16 map3: 1->44 map4: 1->42
2-> 5 6->16 2->67 2-> 7
7-> 8 7-> 8 3->10 7-> 8
现在,比较map1和map2很简单:map1的第一个键低于map2的第一个键,因此map1应该首先出现。
比较map1和map3在第一个条目中给出相同的键,但map1的相应值较低,因此map1再次出现。
比较map1和map4显示第一个键值对完全相同,但比较第二个键对显示map1是第一个,因为它的值再次降低。
按大小排序又是微不足道的。尺寸较小的地图位于尺寸较大的地图之前。
现在完全取决于您,如果您想先按大小排序,或先按键/值排序。 考虑一个额外的地图:
map5: 5->16
7-> 3
map5的大小为2,map1的大小为3.因此,如果先按大小排序,则map5将在map1之前。如果先比较元素,则map1位于map5之前,因为第一个元素较低。
此比较已在C ++中提供:std::pair
提供了operator<
,它首先比较键和后面的值。一般来说,元素集合的元素比较是通过std::lexicographical_compare
完成的。此外,std::map
提供了operator<
,可以为您进行词典比较。它首先比较元素,然后是第二个元素。
但是,在您的情况下,由于您使用char*
而不是C ++的string
,因此您必须为pair<char*, char*>
编写自己的比较器,这些是你的地图。我建议一起使用字符串,它变得非常简单,因为std::string
提供了operator<
:
struct MyStruct
{
string name;
map<string, string> mymap;
};
map<MyStruct,int,Compare> mTest;
//compare function for less then operator
struct Compare
{
bool operator()(const MyStruct &a, const MyStruct&b)
{
return a.name < b.name //name first
|| (a.name == b.name && cmp(a.mymap, b.mymap));
}
bool cmp(map<string, string> const& lhs, map<string, string> const& rhs)
{
return lhs.size() < rhs.size() //size first
|| (lhs.size() == rhs.size() && lhs < rhs);
}
};