【问题标题】:Custom sort ordered map with tuple as keys以元组为键的自定义排序有序映射
【发布时间】:2017-03-20 10:03:57
【问题描述】:

假设我将我的元组定义如下:

typedef tuple<string, string> bigram;

我的地图将元组映射到整数:

map<bigram, int> mymap;

如何自定义我的比较器,以便根据bigram 中第一个字符串的字母顺序对mymap 进行排序?

我在想某处

map<bigram, int, greater<bigrams[0]>> mymap;

【问题讨论】:

    标签: c++ dictionary key tuples


    【解决方案1】:

    首先 - 按字母顺序表示您想要 less 而不是 greater。其次,tuple&lt;string, string&gt; 的默认排序顺序应该适合您。注意:人们给出的各种建议可能并不符合您的要求。当您可能希望将它们视为不同的对象时,它们都会将 {"foo", "bar"}{"foo", "baz"} 进行比较。如果你想要反向排序,你应该可以做map&lt;bigram, int, std::greater&lt;bigram&gt;&gt;,否则坚持简单map&lt;bigram, int&gt;

    元组免费提供的比较运算符的定义参考:http://en.cppreference.com/w/cpp/utility/tuple/operator_cmp

    【讨论】:

      【解决方案2】:

      如果你想要一个正确的比较器,你必须检查元组的每个组件。

      对我来说最好的答案是:

          typedef std::tuple<std::string, std::string> bigrams;
      
          struct bigrams_comp {
              bool operator()(const bigrams& lhs, const bigrams& rhs) {
                  if (std::get<0>(lhs) == std::get<0>(rhs)) {
                      return std::get<1>(lhs) > std::get<1>(rhs);
                  } else {
                  return std::get<0>(lhs) > std::get<0>(rhs);
                  }
              }
          };
      

      否则地图的二分查找会是假的。

      如果我错了,请告诉我。

      【讨论】:

        【解决方案3】:

        将比较器定义为函数或函数对象并将其传递:

        bool comparator( const bigram& a, const bigram& b )
        {
            ...
        }
        std::map<bigram, int, comparator> map;
        

        如果参数已经排序(a 在 b 之前),比较器应该返回 true。

        【讨论】:

          【解决方案4】:

          可以这样实现:

          typedef std::tuple<std::string, std::string> bigrams;
          
          struct bigrams_comp {
              bool operator()(const bigrams& lhs, const bigrams& rhs) {
                  // return std::greater<std::string>()(std::get<0>(lhs), std::get<0>(rhs));
                  return std::get<0>(lhs) > std::get<0>(rhs);
              }
          };
          
          int main()
          {
              std::map<bigrams, int, bigrams_comp> mymap;
          }
          

          【讨论】:

          • std::greater 有什么原因吗?为什么不std::get&lt;0&gt;(lhs) &gt; std::get&lt;0&gt;(rhs)
          • @Rakete1111 因为他在他的问题中使用了更大的
          【解决方案5】:

          您使用了二元组,但定义了二元组,是不是拼写错误?

          比较函数类型必须比较两个Key类型返回一个bool值。

          struct MyCompare
          {
              bool operator()(const bigram &a, const bigram &b) 
              {
                  return std::get<0>(a) > std::get<0>(b);
              }
          };
          
          map<bigram, int, MyCompare> mymap;
          

          【讨论】:

            猜你喜欢
            • 2014-10-06
            • 2011-04-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-28
            • 1970-01-01
            • 1970-01-01
            • 2020-07-03
            相关资源
            最近更新 更多