自定义排序有序映射,以元组为键

时间:2016-11-07 06:07:26

标签: c++ dictionary key tuples

假设我按如下方式定义我的元组:

typedef tuple<string, string> bigram;

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

map<bigram, int> mymap;

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

我正在思考

的某个方面
map<bigram, int, greater<bigrams[0]>> mymap;

5 个答案:

答案 0 :(得分:2)

首先 - 按字母顺序表示您需要less而不是greater。其次,tuple<string, string>的默认排序顺序应该适合您。注意:人们给出的各种建议可能不会做你想要的。当您希望将它们视为不同的对象时,它们都会将{"foo", "bar"}{"foo", "baz"}相等。如果你想要反向排序,你应该能够map<bigram, int, std::greater<bigram>>,否则只能坚持map<bigram, int>

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

可以这样实现:

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;
}

答案 3 :(得分:1)

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

对我来说,好的答案是:

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

否则,地图的二进制搜索将为false。

告诉我,如果我错了。

答案 4 :(得分:0)

你使用bigrams但定义了bigram,这是一个错字吗?

比较函数类型必须比较两个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;