map中所有元素都是pair
pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
所有元素都会根据元素的键值自动排序
本质:
map/multimap属于关联式容器,底层结构是用二叉树实现。
优点:
可以根据key值快速找到value值
map和multimap区别:
map不允许容器中有重复key值元素(value可以重复)
multimap允许容器中有重复key值元素(value可以重复)
1. map容器构造和赋值
// map容器构造和赋值 /* 构造: map<T1, T2> mp; //map默认构造函数: map(const map &mp); //拷贝构造函数 赋值: map& operator=(const map &mp); //重载等号操作符 */ #include <bits/stdc++.h> using namespace std; void printmap1(map<int, int> &m) { for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) { cout << (*it).first << " " << (*it).second << endl; } } void test01() { // 默认构造 map<int, int> m; m.insert(pair<int, int>(1, 10)); m.insert(pair<int, int>(2, 20)); m.insert(pair<int, int>(4, 40)); m.insert(pair<int, int>(3, 30)); printmap1(m); // 10 20 30 40 按key自动升序排序 // 拷贝构造 map<int, int> m2(m); printmap1(m2); // 10 20 30 40 //=赋值 map<int, int> m3; m3 = m2; printmap1(m3); // 10 20 30 40 } int main() { test01(); } /* 总结: map中所有元素都是成对出现,插入数据时候要使用对组 */
2. map大小和交换
// map大小和交换 /* size(); //返回容器中元素的数目 empty(); //判断容器是否为空 swap(st); //交换两个集合容器 */ #include <bits/stdc++.h> using namespace std; void printmap1(map<int, int> &m) { for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) { cout << (*it).first << " " << (*it).second << endl; } } void test01() { // 默认构造 map<int, int> m; m.insert(pair<int, int>(1, 10)); m.insert(pair<int, int>(2, 20)); m.insert(pair<int, int>(4, 40)); m.insert(pair<int, int>(3, 30)); if (m.empty()) { cout << "empty" << endl; } else { cout << "not empty" << endl; cout << m.size() << endl; // 4 } map<int, int> m2; m2.insert(pair<int, int>(12, 10)); m2.insert(pair<int, int>(24, 20)); m2.insert(pair<int, int>(41, 40)); m2.insert(pair<int, int>(35, 30)); printmap1(m); /*1 10 2 20 3 30 4 40*/ printmap1(m2); /*12 10 24 20 35 30 41 40*/ m.swap(m2); printmap1(m); /*12 10 24 20 35 30 41 40*/ printmap1(m2); /*1 10 2 20 3 30 4 40*/ } int main() { test01(); } /* 总结: 统计大小 — size 判断是否为空 — empty 交换容器 — swap */
3. map插入和删除
// map插入和删除 /* insert(elem); //在容器中插入'元素'。 clear(); //清除所有元素 erase(pos); //删除pos'迭代器'所指的元素,返回下一个元素的迭代器。 erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。 erase(key); //删除容器中键值为key的元素。 */ #include <bits/stdc++.h> using namespace std; void printmap1(map<int, int> &m) { for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) { cout << (*it).first << " " << (*it).second << endl; } } void test01() { map<int, int> m; // 插入 m.insert(pair<int, int>(1, 10)); m.insert(make_pair(2, 20)); // 一般用这种 m.insert(map<int, int>::value_type(3, 30)); // 不用记 m[4] = 40; // 不太建议用,因为m[5]若无值,则输出时输出key=5,value=0 printmap1(m); // 1 10 2 20 3 30 4 40 cout << endl; //[]不建议插数,但可以用[]来用key访问value cout << m[5] << endl; // 0 cout << endl; // 删除 m.erase(m.begin()); // 用pos删除 printmap1(m); // 2 20 3 30 4 40 5 0 cout << endl; m.erase(3); // 按key删除 printmap1(m); // 2 20 4 40 5 0 cout << endl; m.erase(3); // 若无key=3,则不删 printmap1(m); // 2 20 4 40 5 0 cout << endl; m.erase(m.begin(), ++m.begin()); // 可以++,但不能+1/+3 printmap1(m); // 4 40 5 0 cout << endl; m.clear(); // 清空 printmap1(m); } int main() { test01(); } /* 总结: map插入方式很多,记住其一即可 插入 — insert 删除 — erase 清空 — clear */
4. map查找和统计
// map查找和统计 /* find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end(); count(key); //统计key的元素个数 */ #include <bits/stdc++.h> using namespace std; void printmap1(map<int, int> &m) { for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) { cout << (*it).first << " " << (*it).second << endl; } } void test01() { // 查找 map<int, int> m; m.insert(pair<int, int>(1, 10)); m.insert(pair<int, int>(2, 20)); m.insert(pair<int, int>(3, 30)); map<int, int>::iterator pos = m.find(3); if (pos != m.end()) { cout << "find" << endl; // √ cout << (*pos).first << " " << (*pos).second << endl; // 3 30 } else { cout << " not find" << endl; } // 统计 map无重复key int num = m.count(3); cout << "num=" << num << endl; // 1 } int main() { test01(); } /* 总结: 查找 — find (返回的是迭代器) 统计 — count (对于map,结果为0或者1;对于multimap,结果可以>0) */
5. map容器排序
5.1内置数据类型的排序
// map容器排序(默认升序) /* 利用仿函数,可以改变排序规则(改为降序) */ #include <bits/stdc++.h> using namespace std; class cmp // 仿函数 { public: bool operator()(int k1, int k2) { return k1 > k2; } }; void test01() { // 查找 map<int, int> m; m.insert(pair<int, int>(1, 10)); m.insert(pair<int, int>(4, 40)); m.insert(pair<int, int>(5, 50)); m.insert(pair<int, int>(2, 20)); m.insert(pair<int, int>(3, 30)); for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) { cout << (*it).first << " " << (*it).second << endl; // 1 10 2 20 3 30 4 40 5 50 } cout << endl; map<int, int, cmp> m2; m2.insert(pair<int, int>(1, 10)); m2.insert(pair<int, int>(4, 40)); m2.insert(pair<int, int>(5, 50)); m2.insert(pair<int, int>(2, 20)); m2.insert(pair<int, int>(3, 30)); for (map<int, int>::iterator it = m2.begin(); it != m2.end(); it++) { cout << (*it).first << " " << (*it).second << endl; // 5 50 4 40 3 30 2 20 1 10 } } int main() { test01(); } /* 总结: 利用仿函数可以指定map容器的排序规则 对于自定义数据类型,map必须要指定排序规则,同set容器 */
5.2自定义数据类型的排序
// map容器排序(默认升序) /* 利用仿函数,可以改变排序规则(改为降序) */ #include <bits/stdc++.h> using namespace std; class person { public: person(string name, int age) { this->name = name; this->age = age; } string name; int age; }; class cmp // 仿函数 { public: bool operator()(person k1, person k2) { return k1.age > k2.age; // 按年龄排序 } }; void test01() { // 查找 map<person, int, cmp> m; person p1("A", 11); person p2("B", 22); person p3("C", 33); person p4("D", 44); person p5("E", 55); m.insert(pair<person, int>(p1, 10)); m.insert(pair<person, int>(p3, 40)); m.insert(pair<person, int>(p4, 50)); m.insert(pair<person, int>(p2, 20)); m.insert(pair<person, int>(p5, 30)); for (map<person, int>::iterator it = m.begin(); it != m.end(); it++) { cout << (*it).first.name << " " << (*it).first.age << " " << (*it).second << endl; } /* E 55 30 D 44 50 C 33 40 B 22 20 A 11 10 */ } int main() { test01(); } /* 总结: 利用仿函数可以指定map容器的排序规则 对于自定义数据类型,map必须要指定排序规则,同set容器 */