(1)map容器的定义概念
1.map容器基本概念与基本用途
基本概念:
map是STL的一个关联容器。
map容器能够自动建立一对一的数据对应关系,即Key-Value的对应关系。
其中Key 和Value可以是程序员指定的任意类型。
(可以把它当作一本字典,key就是索引,value就是翻译,在一本字典中,索引不会重复,但是单词的意思会有重复)
在map内部所有的数据都是有序的,默认的排序方式是根据key的字典序从小到大排列,我们后面会讲如何像sort一样自定义排序方式
基本用途:
根据key值快速查找记录,查找的复杂度基本是O(logN).
快速插入一对Key-Value
快速删除一对Key-Value
根据Key修改value。
遍历所有Key-Value对。
2.我们该如何创建一个map
头文件:include<map>
创建 :map<typename1,typename2> name
(2)对map容器可以进行的操作
1.插入键值对:
方法1:直接赋值法
map<string,int> mp {
{ " john" , 18},
{ " lisa " , 19 },
{" herrny " , 20 },
};
方法2:用insert函数插入pair数据
map<string , int > mp;
mp.insert(pair<string,int>("jonh" , 18) );
mp.insert(pair<string,int>("lisa" , 19) );
mp.insert(pair<string,int>("herrny",20) );
方法3 : 用数组方式插入数据
map<int , string > mp;
m[1]="lx";
m[2]="louis";
这边说一下方法3和方法2的区别:
用insert函数插入数据时,当集合中含有一样的key的时候,就会插入失败。
而用map插入的时候,当集合中含有一样的key的时候,仍然可以插入,只不过把先前的value覆盖了,所以数组插入起到一个数据更新的作用。
2.求map的大小:
size函数:
map<int , int >mp;
for(int i=1;i<=10;i++)
mp[i]=i;
cout<<mp.size();
3.遍历map内的元素:
使用迭代器:
int main()
{
map<int, string> mp;
string s = "abcdefghijklmhopqrstuvwxyz";
//reverse(s.begin() , s.end());
for (int i = 0; i < 26; i++)
mp[i] = s[i];
for (auto it = mp.begin(); it != mp.end(); it++)
cout << it->first << ' '<<it->second<<endl;
}
使用数组下标:
int main()
{
map<int, string> mp;
string s = "abcdefghijklmhopqrstuvwxyz";
//reverse(s.begin() , s.end());
for (int i = 0; i < 26; i++)
mp[i] = s[i];
for (int i = 1; i <= 25; i++)
cout << mp[i];
}
4.查找并获取map中的元素(包括判断这个key是否出现在map中)
第一种:count函数
count函数判定关键字是否出现。缺点是无法返回key出现的位置。因为count函数只能返回0 不出现 或 1 出现 这两种情况。
第二种:find()函数
用find()函数来定位数据出现的位置,如果查到了,将会返回该位置的迭代器,如果没有查到,就会返回指向end 的迭代器。需要注意的是,我们查找都是用key值进行查找。
int main()
{
map<int, string> mp;
string s = "abcdefghijklmhopqrstuvwxyz";
for (int i = 0; i < 26; i++)
mp[i] = s[i];
auto i=mp.find(11);
cout << i->first << ' ' << i->second;
}
第三种:lower_bound(key) 与 upper_bound(key) 函数
lower_bound(key) 与 upper_bound(key) 函数的用法
lower_bound 函数的作用是返回要查找的关键字的上界(是一个迭代器)。
upper_bound 函数的作用是返回要查找的关键字的下界(是一个迭代器)。
例如:map中已经插入了1,2,3,4的话,如果lower_bound(2)的话,返回的2,而upper-bound(2)的话,返回的就是3.
切记查找的只能是key值。
若map里面没有这个key,那么lower_bound(key) 和 upper_bound(key) 返回的迭代器将会是同一个,并且这个迭代器是无法输出的。
所以我们每次查找之前,最好用if判断一下,如果lower_bound(key) == upper_bound (key)
说明没有找到。
4.从map中删除元素
删除某个元素,我们一般用erase()有一下几种删除的方法:
第一种:通过迭代器删除(一般用find):
删除一个键值对:
int main()
{
map<int, string> mp;
string s = "abcdefghijklmhopqrstuvwxyz";
for (int i = 0; i < 26; i++)
mp[i] = s[i];
auto i = mp.find(10);
mp.erase(i);
}
删除一个范围的键值对:
int main()
{
map<int, string> mp;
string s = "abcdefghijklmhopqrstuvwxyz";
for (int i = 0; i < 26; i++)
mp[i] = s[i];
auto i = mp.find(10);
auto j = mp.find(17);
mp.erase(i, j);
for (auto i = mp.begin(); i != mp.end(); i++)
cout << i->first << ' ' << i->second << endl;
}
第二种:通过指定key删除:
int main()
{
map<int, string> mp;
string s = "abcdefghijklmhopqrstuvwxyz";
for (int i = 0; i < 26; i++)
mp[i] = s[i];
cout<<mp.erase(1);
}
通过key删除的话,是有返回值的,如果成功删除了,就会返回1,否则返回0.
map的简单排序问题
我们都直到map函数是按照key值进行升序排列的
假如我们有一天需要降序排列应该怎么办。
这时候我们就需要用到仿函数:
什么是仿函数:
仿函数是一个类或结构体,它重载了圆括号操作符 "()",正常情况下,我们调用函数必须是函数名加上括号。
struct cmp {
bool operator()(int a, int b)const
{
return a > b;
}
};
第一:为什么不使用sort
因为map函数的迭代器是双向迭代器,所以我们只能在一个map的创建之初就规定好map的排序规则。
只有vector 这种 随机迭代器,才可以 使用sort函数。
第二:为什么要建立一个结构体,然后再在里面创建排序函数。
因为map的第三个参数是仿函数,所以我们不能像排序数组和字符串那样把cmp当成一个函数来写,并且,我们必须要重载()才能调用这个仿函数
struct cmp {
bool operator()(int a, int b)const
{
return a > b;
}
};
int main()
{
map<int, string,cmp> mp;
string s = "abcdefghijklmhopqrstuvwxyz";
for (int i = 0; i < 26; i++)
mp[i] = s[i];
for (auto i = mp.begin(); i != mp.end(); i++)
cout << i->first << ' ' << i->second << endl;
}
蒟蒻刚学不久,查了不少东西,但是还是好晕,只能知道最简单的东西,重载运算符啥的根本看不懂哇,呜呜呜呜呜