1.4、map 插入和删除
功能:
map容器进行插入数据和删除数据
函数原型:
insert(elem); 在容器中插入元素。
clear(); 清除所有元素
erase(pos); 删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end); 删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(key); 删除容器中值为key的元素。
代码示例:
// 插入和删除 void test03() { //插入操作 map<int, int> mp; //第一种插入方式 mp.insert(pair<int, int>(1, 10)); //第二种插入方式,推荐 mp.insert(make_pair(2, 20)); //第三种插入方式 mp.insert(map<int, int>::value_type(3, 30)); //第四种插入方式,不推荐:当不存在此值就会自动创建键,值为0 mp[4] = 40; // 模拟误操作 cout << "下标为6的值为:"<<mp[6] << endl; printInfo(mp); //删除,按迭代器 mp.erase(mp.begin()); printInfo(mp); // 删除,按下标 mp.erase(3); mp.erase(6); printInfo(mp); //清空 mp.erase(mp.begin(), mp.end()); mp.clear(); printInfo(mp); }
1.5、map 查找和统计
功能:
对map容器进行查找数据以及统计数据
函数原型:
find(key); 查找key是否存在,若存在,返回该键对应的迭代器;若不存在,返回end();
count(key); 统计key的元素个数
代码示例:
// 查找和统计 void test04() { map<int, int>mp; mp.insert(pair<int, int>(1, 10)); mp.insert(pair<int, int>(2, 20)); mp.insert(pair<int, int>(4, 40)); mp.insert(pair<int, int>(3, 30)); //查找 map<int, int>::iterator pos = mp.find(3); if (pos != mp.end()) { cout << "找到了元素 key = " << (*pos).first << " value = " << (*pos).second << endl; } else { cout << "未找到元素" << endl; } //统计 int num = mp.count(2); cout << "num = " << num << endl; }
2、自定义排序规则
与 set 容器一样,定义排序规则需要在创建容器的时候就指定,同样需要借助仿函数,也就是后面会提到的 谓词
2.1、内置数据类型的排序
// 内置数据类型排序 class descmp { public: bool operator()(int val1, int val2) const { // 指定为降序排列 return val1 > val2; } }; void test05() { cout << "降序排序插入:" << endl; map<int, int,descmp> mp; mp.insert(make_pair(3, 2)); mp.insert(make_pair(7, 4)); mp.insert(make_pair(6, 1)); mp.insert(make_pair(8, 5)); mp.insert(make_pair(1, 3)); for (auto it = mp.begin(); it != mp.end(); it++) { cout << "key = " << it->first << " value = " << it->second << endl; } }
仿函数需要指定为 const 常函数类型,否则将会出现数据不完整错误
2.2、自定义数据类型的排序
进行自定义数据类型排序的时候要注意,使用仿函数定义排序规则是针对 键 的,因此要把定义的类、结构体放在泛型的第一个参数上(别问,问就是我看了半天源码才发现的…)
接下来看看我设计的小案例:
// 自定义数据类型排序 class Hero { public: // 构造方法 Hero(string name, int age) :name(name), age(age) {} // 属性 string name; int age; }; class Cmp_hero { public: bool operator()(const Hero& h1, const Hero& h2)const { return h1.age < h2.age; } }; void test06() { map<Hero, int, Cmp_hero> mh; Hero h1("赵云", 42); Hero h2("曹操", 43); Hero h3("孙策", 39); Hero h4("刘备", 40); Hero h5("关羽", 41); mh.insert(make_pair(h1, 12000)); mh.insert(make_pair(h2, 14000)); mh.insert(make_pair(h3, 10000)); mh.insert(make_pair(h4, 18000)); mh.insert(make_pair(h5, 16000)); for (auto t = mh.begin(); t != mh.end(); t++) { cout << "姓名:" << t->first.name << " 年龄:" << t->first.age << " 赏金:" << t->second << endl; } }
其实更合理的设计应该是按照赏金大小来排序,我之所以这样设计是想介绍一下当键是类的时候该怎么处理:仿函数参数列表中的变量若是 引用形式 必须用 const 修饰(若不是引用形式则不用加 const),而且函数也应该是常函数。
map 容器键值对存储的使用是非常广泛的,下篇博客来做一个员工分组的具体案例,巩固一些 STL常用容器的使用,大家可以订阅专栏,方便查阅和复习。