key=string
且value=int
的map空容器。#include <map> int main(int argc, char * argv[]) { std::map<std::string, int> map_values; return 0; }
#include <map> int main(int argc, char * argv[]) { std::map<std::string, int> map_values {{"A", 1}, {"B", 2}}; return 0; }
make_pair()
初始化map容器。#include <map> int main(int argc, char * argv[]) { std::map<std::string, int> map_values {std::make_pair("A", 1), std::make_pair("B", 2)}; return 0; }
make_pair()
结合insert()
函数插入元素。#include <map> #include <iostream> int main(int argc, char * argv[]) { std::map<std::string, int> map_values {std::make_pair("D", 1), std::make_pair("C", 2)}; auto add_el = std::make_pair("B", 3); map_values.insert(add_el); map_values.insert(std::make_pair("A", 4)); for(auto pair_data : map_values) { std::cout << pair_data.first << " " << pair_data.second << std::endl; } return 0; } // 输出结果 // A 4 // B 3 // C 2 // D 1
从输出结果中可以看出,map容器的顺序是按照key的升序排列的
,并不是插入的顺序。
insert()
函数的返回值是一个pair
对象,该pair对象并不仅仅刚刚插入的元素数据。pair.first
是刚刚要插入的元素
,pair.second
是插入的结果
。#include <map> #include <iostream> int main(int argc, char * argv[]) { std::map<std::string, int> map_values {std::make_pair("D", 1), std::make_pair("C", 2)}; auto add_el = std::make_pair("B", 3); map_values.insert(add_el); map_values.insert(std::make_pair("A", 4)); auto insert_data = map_values.insert(std::make_pair("A", 5)); std::cout << "insert = " << insert_data.first->first << " " << insert_data.first->second << std::endl; std::cout << "insert result = " << std::boolalpha << insert_data.second << std::endl; return 0; } // 输出结果 // insert = A 4 // insert result = false
emplace()
直接在map容器中构造新元素,从而避免复制
和移动
操作。#include <map> #include <iostream> #include <string> class Person { public: Person(int _age, std::string _name) { age = _age; name = _name; } bool operator < (const Person & _person) const { return _person.age < age; } private: int age; std::string name; }; int main(int argc, char * argv[]) { std::map<Person, int> map_values; map_values.emplace(Person{1, "S"}, 10); return 0; }
代码中使用类对象
作为key
值,这种方式需要类对象提供operator < ()
的重载。
at(key)
的方式访问数据,如果不存在会抛出out_of_range
异常。#include <map> #include <string> #include <iostream> class Person { public: Person(int _age, std::string _name) { age = _age; name = _name; } bool operator < (const Person & _person) const { return _person.age < age; } private: int age; std::string name; }; int main(int argc, char * argv[]) { std::map<Person, int> map_values; map_values.emplace(Person{1, "S"}, 10); Person p = {2, "S"}; try { auto value = map_values.at(p); std::cout << value << std::endl; } catch (const std::out_of_range & e) { std::cerr << e.what() << std::endl; } return 0; } // 输出结果 // invalid map<K, T> key
[key]
的方式访问数据,如果不存在会添加该元素。#include <map> #include <string> #include <iostream> int main(int argc, char * argv[]) { std::map<std::string, int> map_values; map_values.insert(std::make_pair("A", 10)); std::cout << map_values.size() << std::endl; auto find_value = map_values["A"]; std::cout << map_values.size() << std::endl; find_value = map_values["B"]; std::cout << map_values.size() << std::endl; return 0; }
find(key)
访问元素,该方法返回一个指向该元素的迭代器。#include <map> #include <string> #include <iostream> int main(int argc, char * argv[]) { std::map<std::string, int> map_values; map_values.insert(std::make_pair("A", 10)); auto find_value = map_values.find("A"); if(find_value != map_values.end()) std::cout << find_value->first << ", " << find_value->second << std::endl; return 0; }
erase(key)
函数移除键和对应的值。#include <map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::map<std::string, int> map_values; map_values.insert(std::make_pair("A", 1)); map_values.insert(std::make_pair("B", 2)); map_values.insert(std::make_pair("C", 3)); map_values.insert(std::make_pair("D", 4)); std::cout << map_values.size() << std::endl; int value = map_values.erase("A"); std::cout << value << std::endl; return 0; }
erase(iterator)
函数根据迭代器的位置删除一个元素,返回删除元素所在位置的下个一个元素的迭代器。#include <map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::map<std::string, int> map_values; map_values.insert(std::make_pair("A", 1)); map_values.insert(std::make_pair("B", 2)); map_values.insert(std::make_pair("C", 3)); map_values.insert(std::make_pair("D", 4)); auto next_iter = map_values.erase(map_values.begin()); std::cout << next_iter->first << std::endl; return 0; } // 输出结果 // B
erase(iterator begin, iterator end)
函数移除指定范围的迭代器。#include <map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::map<std::string, int> map_values; map_values.insert(std::make_pair("A", 1)); map_values.insert(std::make_pair("B", 2)); map_values.insert(std::make_pair("C", 3)); map_values.insert(std::make_pair("D", 4)); map_values.erase(++map_values.begin(), --map_values.end()); std::cout << map_values.size() << std::endl; return 0; }
初始化列表
初始化容器。#include <map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::multimap<std::string, int> multimap_values = {{"A", 10}, {"A", 15}}; auto iter = multimap_values.begin(); while (iter != multimap_values.end()) { std::cout << iter->first << ", " << iter->second << std::endl; iter++; } return 0; }
#include <map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::multimap<std::string, int> multimap_values = {{"A", 10}, {"A", 15}}; auto iter = multimap_values.insert(multimap_values.begin(), std::make_pair("A", 5)); while (iter != multimap_values.end()) { std::cout << iter->first << ", " << iter->second << std::endl; iter++; } return 0; } // 输出结果 // A, 5 // A, 10 // A, 15
multimap没有提供at(key)
或者[key]
的访问方式,可以使用find(key)
的方法访问,但是该方法返回的是找到元素所在位置的迭代器,由于multimap可以存储重复key值,因此这个访问也不可取。
equal_range(key)
访问元素,如果找到对应的key则将对应范围内的迭代器全部返回。#include <map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::multimap<std::string, int> multimap_values = {{"A", 10}, {"A", 15}}; multimap_values.insert(multimap_values.begin(), std::make_pair("A", 5)); multimap_values.insert({{"B", 1}, {"A", 1}, {"B", 5}}); auto find_result = multimap_values.equal_range("B"); if (find_result.first != multimap_values.end()) { while (find_result.first != find_result.second) { std::cout << find_result.first->first << ", " << find_result.first->second << std::endl; find_result.first++; } } return 0; } // 输出结果 // B, 1 // B, 5
lower_bound(key)
返回一个指向和参数相等
或大于
参数的第一个元素的迭代器,或指向结束位置的迭代。#include <map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::multimap<std::string, int> multimap_values = {{"A", 10}, {"A", 15}}; multimap_values.insert({{"B", 1}, {"C", 1}, {"A", 1}, {"B", 5}}); auto find_result = multimap_values.lower_bound("B"); while (find_result != multimap_values.end()) { std::cout << find_result->first << ", " << find_result->second << std::endl; find_result++; } return 0; } // 输出结果 // B, 1 // B, 5 // C, 1
upper_bound(key)
返回一个指向和参数大于
参数的第一个元素的迭代器,或指向结束位置的迭代。#include <map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::multimap<std::string, int> multimap_values = {{"A", 10}, {"A", 15}}; multimap_values.insert({{"B", 1}, {"C", 1}, {"A", 1}, {"B", 5}}); auto find_result = multimap_values.upper_bound("B"); while (find_result != multimap_values.end()) { std::cout << find_result->first << ", " << find_result->second << std::endl; find_result++; } return 0; } // 输出结果 // C, 1
erase(key)
删除全部对应键的元素。#include <map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::multimap<std::string, int> multimap_values = {{"A", 10}, {"A", 15}}; multimap_values.insert({{"B", 1}, {"C", 1}, {"A", 1}, {"B", 5}}); size_t count = multimap_values.erase("A"); std::cout << "remove count " << count << std::endl; auto find_result = multimap_values.begin(); while (find_result != multimap_values.end()) { std::cout << find_result->first << ", " << find_result->second << std::endl; find_result++; } return 0; } // 输出结果 // remove count 3 // B, 1 // B, 5 // C, 1
erase(iterator __position)
或者erase(const_iterator __first, const_iterator __last)
删除从指定迭代器范围的数据,返回一个指向最后一个被删除元素之后的迭代器。#include <map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::multimap<std::string, int> multimap_values = {{"A", 10}, {"A", 15}}; multimap_values.insert({{"B", 1}, {"C", 1}, {"A", 1}, {"B", 5}}); find_result = multimap_values.erase(++multimap_values.begin()); while (find_result != multimap_values.end()) { std::cout << find_result->first << ", " << find_result->second << std::endl; find_result++; } return 0; } // 输出结果 // C, 1
unordered_map与map一样都是唯一键值
对的元素容器。但与map不同的是其中元素不是有序的,元素的位置由键
的哈希值
确定,因而必须有一个适用与键类型的哈希函数。
哈希表大小
。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_map<std::string, int> u_map_values { {"A", 10}, {"B", 20} }; return 0; }
哈希表大小
。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_map<std::string, int> u_map_values { {{"A", 10}, {"B", 20}, {"C", 30}}, 100 // 哈希表大小 }; return 0; }
insert
函数使用列表批量插入数据。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_map<std::string, int> u_map_values { {{"A", 10}, {"B", 20}, {"C", 30}}, 100 // 哈希表大小 }; u_map_values.insert({{"D", 40},{"E", 50}}); return 0; }
insert
函数使用范围迭代器插入数据。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_map<std::string, int> u_map_values { {{"A", 10}, {"B", 20}, {"C", 30}}, 100 // 哈希表大小 }; u_map_values.insert({{"D", 40},{"E", 50}}); std::unordered_map<std::string, int> copy_map; copy_map.insert(u_map_values.begin(), u_map_values.end()); return 0; }
emplace
函数添加数据。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_map<std::string, int> u_map_values { {{"A", 10}, {"B", 20}, {"C", 30}}, 100 // 哈希表大小 }; u_map_values.emplace("D", 40); return 0; }
通过emplace_hint
函数添加数据到指定位置。
#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_map<std::string, int> u_map_values { {{"ZS", 10}, {"LS", 20}, {"WU", 30}}, 100 // 哈希表大小 }; u_map_values.emplace_hint(++u_map_values.begin(), "ZL", 40); return 0; }
[key]
来访问容器中的元素,如果没有找到对应元素则添加一个元素。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_map<std::string, int> u_map_values { {{"ZS", 10}, {"LS", 20}, {"WU", 30}}, 100 // 哈希表大小 }; std::cout << u_map_values["LS"] << std::endl; return 0; }
at(key)
来访问容器中的元素,如果没有找到对应的元素则抛出out_of_range
异常。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_map<std::string, int> u_map_values { {{"ZS", 10}, {"LS", 20}, {"WU", 30}}, 100 // 哈希表大小 }; std::cout << u_map_values.at("ZS") << std::endl; return 0; }
find(key)
访问元素,该方法返回一个指向该元素的迭代器。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_map<std::string, int> u_map_values { {{"ZS", 10}, {"LS", 20}, {"WU", 30}}, 100 // 哈希表大小 }; std::cout << u_map_values.find("ZS")->second << std::endl; return 0; }
#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_map<std::string, int> u_map_values { {{"ZS", 10}, {"LS", 20}, {"WU", 30}}, 100 // 哈希表大小 }; auto result = u_map_values.erase("ZS"); return 0; }
#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_map<std::string, int> u_map_values { {{"ZS", 10}, {"LS", 20}, {"WU", 30}}, 100 // 哈希表大小 }; auto result = u_map_values.find("ZS"); if(result != u_map_values.end()) u_map_values.erase(result); return 0; }
自定义类型的键需要类对象在实现hash()
和operator==
两个函数。
class Name { public: Name(const std::string _name) { name_ = _name; } /* 必要函数1:生成hash值函数 */ size_t hash() const { size_t hash_code = std::hash<std::string>()(name_); std::cout << "name = " << name_ << ", hash code = " << hash_code << std::endl; return hash_code; } /* 必要函数2:恒等比较函数 */ bool operator==(const Name & _name) const { return name_ == _name.name_; } private: std::string name_; };
在提供一个类其中实现operator()
来调用哈希校验。
class Hash_Name { public: size_t operator()(const Name & _name) const { return _name.hash(); } };
声明容器。
#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_map<Name, int, Hash_Name> u_map_values {{ {{"A"},10}, {{"B"},20} },2, Hash_Name()}; auto result = u_map_values.insert({{"C"},10}); std::cout << std::boolalpha << result.second << std::endl; return 0; }
unordered_multimap是一个允许有重复键的无序map。
哈希表大小
。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_multimap<std::string, int> u_map_values { {"A", 10}, {"B", 20} }; return 0; }
哈希表大小
。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_multimap<std::string, int> u_map_values { {{"ZS", 10}, {"ZS", 20}, {"ZS", 30}, {"BS", 10}}}; return 0; }
insert
函数使用列表批量插入数据。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_multimap<std::string, int> u_map_values { {{"ZS", 10}, {"ZS", 20}, {"ZS", 30}, {"BS", 10}}, 100 // 哈希表大小 }; u_map_values.insert({{"BS", 40},{"BS", 50}}); return 0; }
insert
函数使用范围迭代器插入数据。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_multimap<std::string, int> u_map_values { {{"ZS", 10}, {"ZS", 20}, {"ZS", 30}, {"BS", 10}}, 100 // 哈希表大小 }; u_map_values.insert({{"BS", 40},{"BS", 50}}); std::unordered_multimap<std::string, int> copy_map; copy_map.insert(u_map_values.begin(), u_map_values.end()); return 0; }
emplace
函数添加数据。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_multimap<std::string, int> u_map_values { {{"ZS", 10}, {"ZS", 20}, {"ZS", 30}, {"BS", 10}}, 100 // 哈希表大小 }; u_map_values.emplace("D", 40); return 0; }
通过emplace_hint
函数添加数据到指定位置。
#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_multimap<std::string, int> u_map_values { {{"ZS", 10}, {"ZS", 20}, {"ZS", 30}, {"BS", 10}}, 100 // 哈希表大小 }; u_map_values.emplace_hint(++u_map_values.begin(), "ZL", 40); return 0; }
equal_range[key]
获取全部对应值的范围迭代器。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_multimap<std::string, int> u_map_values { {{"ZS", 10}, {"ZS", 20}, {"ZS", 30}, {"BS", 10}}, 100 // 哈希表大小 }; auto result_it = u_map_values.equal_range("ZS"); while (result_it.first != result_it.second) { std::cout << "key = " << result_it.first->first << ", value = " << result_it.first->second <<std::endl; ++result_it.first; } return 0; }
count(key)
访问key所对应的值的数量。#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_multimap<std::string, int> u_map_values { {{"ZS", 10}, {"ZS", 20}, {"ZS", 30}, {"BS", 10}}, 100 // 哈希表大小 }; auto result = u_map_values.count("ZS"); std::cout << result << std::endl; return 0; }
#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_multimap<std::string, int> u_map_values { {{"ZS", 10}, {"ZS", 20}, {"ZS", 30}, {"BS", 10}}, 100 // 哈希表大小 }; auto result = u_map_values.erase("ZS"); return 0; }
#include <unordered_map> #include <iostream> #include <string> int main(int argc, char * argv[]) { std::unordered_multimap<std::string, int> u_map_values { {{"ZS", 10}, {"ZS", 20}, {"ZS", 30}, {"BS", 10}}, 100 // 哈希表大小 }; auto result = u_map_values.equal_range("ZS"); int count = u_map_values.count("ZS"); for (int index = 0; index < count; ++index) { u_map_values.erase(result.first++); } std::cout << u_map_values.size() << std::endl; return 0; }