std :: map - 如何更改密钥排序?

时间:2013-05-14 14:03:23

标签: c++ string sorting dictionary stl

我对std::map有疑问。 我用它来映射特定索引下的一些对列表:

map<string, list<pair<string, int> > > List;

它用于Dijkstra算法。 主要问题是map按字母顺序对string个键进行排序,如下所示:

AAA, AA0, AA1, AAB, AC1 = AA0->AA1->AAA->AAB->AC1

但我想以不同的方式对其进行排序:

AAA, AA0, AA1, AAB, AC1 = AAA->AAB->AA0->AA1->AC1

这有什么解决方案吗?我读过关于制作自己的比较课程,但我不知道如何做到这一点。或者也许有其他方法可以解决它?

4 个答案:

答案 0 :(得分:9)

您必须提供自己的比较仿函数,在实例化地图时必须将其作为第三个模板参数传递。例如:

struct Comp
{
  bool operator()(const std::string& lhs, const std::string& rhs) const
  {
    // implement your comparison logic here
  }
};

这个类的实例是可调用的(因此是“functor”),带有两个字符串参数,并且应该基于strict weak ordering逻辑返回true或false。

然后使用仿函数类型实例化地图:

std::map<string, list<pair<string, int>>, Comp> List;

现在,地图将在内部使用您的比较逻辑来定义其元素的排序。

答案 1 :(得分:3)

正如其他人所说,你需要实现一个自定义比较器......

struct custom_comparer
{
    bool operator()(const std::string& left, const std::string& right) const
    {
        return std::lexicographical_compare(
            left.cbegin(), left.cend(), 
            right.cbegin(), right.cend(),
            [](char l, char r) -> bool
            {
                 bool ldigit = isdigit(l) != 0,
                      rdigit = isdigit(r) != 0;

                 return (!ldigit && rdigit) || (ldigit == rdigit && l < r);
            });
    }
};

并使用它......

std::map<string, list<pair<string, int>>, custom_comparer> List;

普通string比较运算符使用lexicographical_compare。我上面的custom_comparer也使用了它,但插入了自定义比较器。自定义比较器使用isdigit进行您想要的比较。

答案 2 :(得分:2)

你必须编写自己的比较器:

struct custom_string_comparer
{
    bool operator()(const std::string& s1, const std::string& s2)
    {
         return ...; // your comparison here
    }
};

map<string, list<pair<string, int>>, custom_string_comparer> List;

答案 3 :(得分:-3)

是。您需要提供第三个模板参数,请参阅docs