【问题标题】:std::map - how to change key sorting?std::map - 如何更改键排序?
【发布时间】:2013-05-08 20:38:04
【问题描述】:

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

有什么解决办法吗?我读到了关于制作自己的比较类的文章,但我不知道该怎么做。还是有其他方法可以解决?

【问题讨论】:

    标签: c++ string sorting dictionary stl


    【解决方案1】:

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

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

    这个类的实例可以用两个字符串参数调用(因此是“函子”),并且应该根据strict weak ordering 逻辑返回真或假。

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

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

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

    【讨论】:

    • 好的,我知道了,但是如何比较字符串的差异?我的意思是,我怎样才能在字符串中找到一个数字?
    • @user2342783 这是一个完全不同的问题。你应该在一个新问题中提出这个问题
    • @user2342783 这是一个不同的问题。但是您可以遍历字符串的元素(每个元素都是char),然后对它们执行诸如调用std::isdigit 之类的操作。
    【解决方案2】:

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

    【讨论】:

    • 虽然你的说法是正确的,但它本身并没有帮助。至少像其他人一样写下一个最小的例子。此外,cplusplus.com 不是文档。
    【解决方案3】:

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

    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;
    

    【讨论】:

      【解决方案4】:

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

      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 进行您想要的比较。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-19
        • 2012-05-27
        • 2015-12-04
        • 1970-01-01
        • 1970-01-01
        • 2014-04-30
        相关资源
        最近更新 更多