对组
首先我们需要了解什么是对组,对组(pair)可将两个值合成一个值,这两个值可以具有不同的数据类型,可以分别用pair的两个公有函数first和second访问。
类模板:template<class T1,class T2>struct pair.
对组的创建有三种方法:
pair<string,int>pair1(string("name"),20);
pair<string,int>pair2 = make_pair("name",30);
pair<string,int>pair3 = pair1;
cout << pair1.first << endl;//访问第一个元素
cout << pair1.second << endl;//访问第二个元素
map
map是STL的一个关联容器,它提供一对一的hash,使用时需要#include<map>。第一个值可以称为关键字(key),每个关键字只能在map中出现一次;第二个值称为该关键字的值(value)。map以红黑树为底层实现机制,会根据键值(key)自动排序。
map不允许相同键值存在,不能通过迭代器修改键值,只能修改实质值。
五种初始化方法
map<int,int>mymap;
mymap = {{1,1}};//这种方式可以在声明时候初始化,不过这不是插入而是赋值,如果map里之前有元素会被清除
mymap.insert(pair<int,int>(10,10));
mymap.insert(make_pair(20,20));
mymap.insert(map<int,int>::value_type(30,30));
mymap[40] = 40;
insert方法可以插入多值:
//指定位置插入,效率更高
std::map<char, int>::iterator it = mymap.begin();
mymap.insert(it, std::pair<char, int>('b', 300));
//范围多值插入
std::map<char, int> anothermap;
anothermap.insert(mymap.begin(), mymap.find('c'));
// 列表形式插入
anothermap.insert({ { 'd', 100 }, {'e', 200} });
打印:
//方法一
for(map<int,int>::iterator it = mymap.begin();it!=mymap.end();it++)
{
//*it就是一个pair
cout << "key:" << (*it).first << "value:" << it->second << endl;
}
//方法二
for (auto it:mymap)
{
//it就是一个pair
cout << "key:" << it.first << "value:" << it.second << endl;
}
判断是否插入成功:
使用insert向map中插入pair后会有返回值,返回值类型为pair<iterator,bool>,如果插入成功bool为true,失败则为false。
map<int, int>mymap;
pair<map<int,int>::iterator,bool>ret = mymap.insert(pair<int, int>(10, 10));
if (ret.second)cout << "第一次插入成功" << endl;
else cout << "第一次插入失败" << endl;
ret = mymap.insert(make_pair(10, 20));
if (ret.second)cout << "第二次插入成功" << endl;
else cout << "第二次插入失败" << endl;
mymap.insert(map<int, int>::value_type(30, 30));
mymap[40] = 40;
mymap[40] = 50;
cout << mymap[60] << endl;
for (map<int, int>::iterator it = mymap.begin(); it != mymap.end(); it++)
{
//*it就是一个pair
cout << "key:" << (*it).first << "value:" << it->second << endl;
}
输出结果:
前三种方法插入时如果key已经存在,将会插入失败。如果使用mymap[40] = 40这种插入方法如果key存在,对应value将会被新插入的值覆盖。如果通过mymap[60]这种方法访问map中不存在的值,将会在map中插入访问的key值,并给value默认初始化值。
取值:
map可以通过[]和.at()的方式取值,[]效率更高,.at()会检测是否越界,具体可以参考这里。
map的操作:
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数,查询关键字为key的元素的个数,在map里结果非0即1
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对,即pair< lower_bound(),upper_bound() >
erase() 删除一个元素,括号里可以是键值、可以是迭代器、也可以是两个迭代器表示删除多个元素
find() 查找一个元素,关键字查询,找到则返回指向该关键字的迭代器,否则返回指向end的迭代器
insert() 插入元素,上面有详细介绍
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器,不等于end()
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
map插入自定义类型key
前面知道了map在插入元素时会对里面键值对按key的值排序,如果我们的key为自定义数据类型,比如:
class MyKey
{
public:
MyKey(int index, int id)
{
this->index1 = index;
this->index1 = id;
}
public:
int index1;
int index2;
};
此时需要新定义一个比较函数:
struct mycompare
{
bool operator()(MyKey key1,MyKey key2)
{
return key1.index1 > key2.index1;
}
};
在声明map时加入这个比较函数:
map<MyKey, int, mycompare>mymap;
然后我们就可以向map插入元素了:
mymap.insert(make_pair(MyKey(3, 4), 20));