有时候不得不说自己的速度真慢,补了一次蓝桥杯的模拟赛的题补了三天,最后一道题现在还是懵,按下这个学习一下STL中的map容器:
关于map,先说一下,它就像Python中字典,是由键值对构成的,这样说吧,如果数组使用下标和值一一对应的,那么map里面是用键和值一一对应的,因为下标唯一,所以键在map中也是唯一的不会相同,值当然随你咯。
但是在stl里面它的存取查找速度是非常快的,内部用的是红黑树因实现的(还自带排序功能,后面你会体验到),因此不用担心时间效率问题,是O(log n)级别的, 也就是里面有1000个元素,查找等操作也就最多10次就OK,可能内存有点大(这也是无可避免的,鱼和熊掌不能兼得嘛),一般应该也没有什么问题。
一、首先声明,定义:
头文件不用说了肯定是:
#include<map>
定义的话最常用的是这样,一般也就够用了:
map<string , int> st;//string 是键的类型,int是值得类型,两个的数据类型可以是任何数据类型,随你咯。(这里要包含#include<string>头文件)
二、元素赋值,插入操作:
1、用insert函数插入pair数据,(实在点,就是一种插入数据的方法):
st.insert(pair<string, int>("XueSheng1", 1));
st.insert(pair<string, int>("XueSheng2", 2));
st.insert(pair<string, int>("XueSheng3", 3));
2、用insert函数插入value_type数据
st.insert(map<string, int> ::value_type("XueSheng4", 4));
3、数组的形式插入
st["XueSheng5"] = 5;
这里要说明一下,前两种的插入效果是一样的,如果要插入的键不存在会插入成功,如果存在,则插入不成功,自己可以尝试一下;最后一种插入方法不管该键是否存在,都会成功,即如果存在,后者会覆盖前者。
三、元素的查找操作
这里要先说一下:
map<string, int> ::iterator iter;
这里是你所定义的map类型的迭代器(其实说的白一点,你就可以把它当做C语言里面你定义的类型的指针)
1、可以通过find()函数
iter = st.find("XueSheng1");
cout<<iter->first<<' '<<iter->second<<endl;
\\要是用printf的话可以这样:
printf("%s %d\n", iter->first.c_str(), iter->second);
这里first指的是键,second指的是值;find返回的是该类型的迭代器(即说白了的指针。。。随你咯),如果要查找的键不存在,会返回指向其末尾的迭代器st.end();
printf("XueSheng1 是否存在(输出1存在,输出0不存在):\n");
printf("%d\n", iter == st.end() ? 0 : 1);
另外,如果知道存在的话,可以直接以数组的形式直接访问。
printf("%d\n", st["XueSheng1"]);
四、遍历
这个应该很容易理解:
for(map<string, int> ::iterator iter = st.begin(); iter != st.end(); iter++)
printf("%s %d\n", iter->first.c_str(), iter->second);
或者反向迭代:
for(map<string, int> ::reverse_iterator iter2 = st.rbegin(); iter2 != st.rend(); iter2++)
{
printf("%s %d\n", iter2->first.c_str(), iter2->second);
}
如果是map<int, string> stu;的话,最好不要采用数组的形式访问
map<int, string> stu;
stu.insert(pair<int, string> (1, "s1"));
stu.insert(pair<int, string> (2, "s2"));
stu.insert(pair<int, string> (4, "s4"));
for(int i = 1; i <= stu.size(); i++)\\这里一定是i=1开始,你可以stu.insert(pair<int, string> (0, "s0"));,从i=0开 // 始试试
{
printf("%s\n", stu[i].c_str());
}
五、删除元素
用erase()函数具体见栗子:
///1.用迭代器删除一个元素:
map<int, string> ::iterator iter1;
iter1 = stu.find(1);
stu.erase(iter1);
iter1 = stu.find(1);
printf("1 是否存在(输出1存在,输出0不存在):\n");
printf("%d\n", iter1 == stu.end() ? 0 : 1);
///2.删除一个范围的元素:
stu.erase(stu.begin(), stu.end());
printf("1为成功,0为不成功:\n");
printf("%d\n", stu.empty() ? 1 : 0);
///用键删除一个元素:
stu[3] = "s3";
stu.erase(3);
printf("1为成功,0为不成功:\n");
printf("%d\n", stu.find(3) == stu.end() ? 1 : 0);
如果直接清空 也可以用clear()函数:
st.clear();
printf("st是否为空(1.是;2.不空):\n");
printf("%d\n", st.empty() ? 1 : 0);
最后常用函数:
st.begin() 返回指向容器开头的迭代器
st.end() 返回指向容器末尾的迭代器
st.erase() 清除元素的函数
st.clear() 清空容器的函数
st.find() 返回所查键的迭代器,如果不存在,则返回容器末尾的迭代器
st.empty() 判断容器是否为空函数
st.insert() 插入函数,若准备插入的键已存在,则插入不成功,否, 则成功
st.size() 返回容器中元素的个数
\\在map中输出string类型的键或值,用printf可以用 iter->first.c_str(), 或者iter->second.c_str()