typedef map<string, string> myMap;
При вставке новой пары в myMap
, он будет использовать ключ string
для сравнения своим собственным компаратором строк. Можно ли отменить этот компаратор? Например, я хотел бы сравнить ключ string
по длине, а не по алфавиту. Или есть другой способ отсортировать карту?
std::map<std::string, std::string> myMap(cmpByStringLength());
cmpByStringLength
не экземпляромstd::less<std::string>
. Для общей карты, которая может иметь любой компаратор, установленный в конструкторе, вам понадобится что-то вродеstd::map<std::string, std::string, std::function<bool(const std::string &, const std::string &)>> myMap(cmpByStringLength);
Начиная с 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;
Вывод:
Я хотел бы повторить последнее примечание ответа Георга: при сравнении по длине у вас может быть только одна строка каждой длины на карте в качестве ключа.
Код на Ideone
источник
Да, третий параметр шаблона
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"; }
источник
std::binary_function
? Это нужно?std::binary_function
удален в С ++ 17, поэтому этот ответ, вероятно, может использовать обновление.Укажите тип указателя на вашу функцию сравнения в качестве 3-го типа в карте и укажите указатель функции на конструктор карты:
map<keyType, valueType, typeOfPointerToFunction> mapName(pointerToComparisonFunction);
Взгляните на приведенный ниже пример для предоставления функции сравнения
map
сvector
итератором в качестве ключа иint
значения.#include "headers.h" bool int_vector_iter_comp(const vector<int>::iterator iter1, const vector<int>::iterator iter2) { return *iter1 < *iter2; } int main() { // Without providing custom comparison function map<vector<int>::iterator, int> default_comparison; // Providing custom comparison function // Basic version map<vector<int>::iterator, int, bool (*)(const vector<int>::iterator iter1, const vector<int>::iterator iter2)> basic(int_vector_iter_comp); // use decltype map<vector<int>::iterator, int, decltype(int_vector_iter_comp)*> with_decltype(&int_vector_iter_comp); // Use type alias or using typedef bool my_predicate(const vector<int>::iterator iter1, const vector<int>::iterator iter2); map<vector<int>::iterator, int, my_predicate*> with_typedef(&int_vector_iter_comp); using my_predicate_pointer_type = bool (*)(const vector<int>::iterator iter1, const vector<int>::iterator iter2); map<vector<int>::iterator, int, my_predicate_pointer_type> with_using(&int_vector_iter_comp); // Testing vector<int> v = {1, 2, 3}; default_comparison.insert(pair<vector<int>::iterator, int>({v.end(), 0})); default_comparison.insert(pair<vector<int>::iterator, int>({v.begin(), 0})); default_comparison.insert(pair<vector<int>::iterator, int>({v.begin(), 1})); default_comparison.insert(pair<vector<int>::iterator, int>({v.begin() + 1, 1})); cout << "size: " << default_comparison.size() << endl; for (auto& p : default_comparison) { cout << *(p.first) << ": " << p.second << endl; } basic.insert(pair<vector<int>::iterator, int>({v.end(), 0})); basic.insert(pair<vector<int>::iterator, int>({v.begin(), 0})); basic.insert(pair<vector<int>::iterator, int>({v.begin(), 1})); basic.insert(pair<vector<int>::iterator, int>({v.begin() + 1, 1})); cout << "size: " << basic.size() << endl; for (auto& p : basic) { cout << *(p.first) << ": " << p.second << endl; } with_decltype.insert(pair<vector<int>::iterator, int>({v.end(), 0})); with_decltype.insert(pair<vector<int>::iterator, int>({v.begin(), 0})); with_decltype.insert(pair<vector<int>::iterator, int>({v.begin(), 1})); with_decltype.insert(pair<vector<int>::iterator, int>({v.begin() + 1, 1})); cout << "size: " << with_decltype.size() << endl; for (auto& p : with_decltype) { cout << *(p.first) << ": " << p.second << endl; } with_typedef.insert(pair<vector<int>::iterator, int>({v.end(), 0})); with_typedef.insert(pair<vector<int>::iterator, int>({v.begin(), 0})); with_typedef.insert(pair<vector<int>::iterator, int>({v.begin(), 1})); with_typedef.insert(pair<vector<int>::iterator, int>({v.begin() + 1, 1})); cout << "size: " << with_typedef.size() << endl; for (auto& p : with_typedef) { cout << *(p.first) << ": " << p.second << endl; } }
источник