Как я могу создать свой собственный компаратор для карты?
typedef map<string, string> myMap;
при вставке новой пары myMap
он будет использовать ключ string
для сравнения с помощью собственного строкового компаратора. Можно ли переопределить этот компаратор? Например, я хотел бы сравнить ключ string
по его длине, а не по алфавиту. Или есть другой способ сортировки карты?
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;
В качестве альтернативы вы также можете передать компаратор в
map
s конструктор.обратите внимание, однако, что при сравнении по длине вы можете иметь только одну строку каждой длины на карте в качестве ключа.
да, 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
два
три
фууурЯ хотел бы повторить заключительную ноту ответа Георга: при сравнении по длине вы можете иметь только одну строку каждой длины на карте в качестве ключа.