Как я могу создать свой собственный компаратор для карты?


typedef map<string, string> myMap;

при вставке новой пары myMap он будет использовать ключ string для сравнения с помощью собственного строкового компаратора. Можно ли переопределить этот компаратор? Например, я хотел бы сравнить ключ string по его длине, а не по алфавиту. Или есть другой способ сортировки карты?

3 57

3 ответа:

std::map принимает до четырех аргументов типа шаблона, третий из которых является компаратором. Например:

struct cmpByStringLength {
    bool operator()(const std::string& a, const std::string& b) const {
        return a.length() < b.length();
    }
};

// ...
std::map<std::string, std::string, cmpByStringLength> myMap;

В качестве альтернативы вы также можете передать компаратор в maps конструктор.

обратите внимание, однако, что при сравнении по длине вы можете иметь только одну строку каждой длины на карте в качестве ключа.

да, 3-й параметр шаблона на map указывает компаратор, который является двоичным предикатом. Пример:

struct ByLength : public std::binary_function<string, string, bool>
{
    bool operator()(const string& lhs, const string& rhs) const
    {
        return lhs.length() < rhs.length();
    }
};

int main()
{
    typedef map<string, string, ByLength> lenmap;
    lenmap mymap;

    mymap["one"] = "one";
    mymap["a"] = "a";
    mymap["fewbahr"] = "foobar";

    for( lenmap::const_iterator it = mymap.begin(), end = mymap.end(); it != end; ++it )
        cout << it->first << "\n";
}

С C++11, вы также можете использовать лямбда-выражение вместо определения структуры компаратора:

auto comp = [](const string& a, const string& b) { return a.length() < b.length(); };
map<string, string, decltype(comp)> my_map(comp);

my_map["1"]      = "a";
my_map["three"]  = "b";
my_map["two"]    = "c";
my_map["fouuur"] = "d";

for(auto const &kv : my_map)
    cout << kv.first << endl;

выход:

1
два
три
фууур

Я хотел бы повторить заключительную ноту ответа Георга: при сравнении по длине вы можете иметь только одну строку каждой длины на карте в качестве ключа.

код на Ideone