如何为包含map的struct编写比较运算符?

时间:2014-03-19 09:25:25

标签: c++ map

我的结构如下:

   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撰写比较?

这基本上是我想要的:

如果

,两张地图相同
  1. 名称相等

  2. 他们的地图大小相等

  3. 那么地图的内容应该是相同的,即它们的键和值。

2 个答案:

答案 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实施其他运算符,并按照我上面所做的那样通过调用namemymap的逻辑运算符来编写它们,你不需要自己实施任何自定义黑客攻击。

答案 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); 
  }
};