C++ 部分STL
- map
map可以理解为一个数组(但实质上并不是,只是方便理解),我们一般的数组不管定义成什么类型他的下标都是整型(int),map和这些数组的区别是他的下标可以是其他类型,由自己定义。map的创建、插值和访问示例如下:
#include"cstdio"
#include"string" #include"map" using namespace std; //尖括号里两个数据类型,第一个可以理解为数组下标的类型,第二个就是数组的数据类型; map<string,int>mp; int main(){ mp["one"]=1; mp["two"]=2; printf("%d\n",mp["one"]+mp["two"]); //结果显然是3; printf("%d\n",mp["three"]); //结果是0; //由于未插入"three"的值,所以"three"的值默认为0;这里要注意是在查询"three"前发现mp中没有"three"而给"three"插入了0的值 //为什么这么说呢?因为在执行完上面的代码之后,mp里面有三条记录,也就是说"three"对应的是0,而"four"则是不存在 return 0; }
NOTE:map这个“数组”会把记录按照下标排序。比如我先插入了mp["b"];再插入mp["a"],mp["a"]会到mp["b"]的前面去;在下面的遍历代码中可以体现;
map的遍历代码如下:
#include"cstdio" #include"string" #include"iostream" #include"map" using namespace std; map<string,int>mp; int main(){ mp["one"]=1; mp["two"]=2; mp["three"]=3; mp["four"]=4; for(map<string,int>::iterator it=mp.begin();it!=mp.end();it++) cout<< it->first << ":" << it->second <<" "; /* 结果是:four:4 one:1 three:3 two:2 由此可以看出不是按输入顺序的 */ cout<<endl; //C++11版本之后推出了一种更方便的遍历方式 //map中每一条记录都是一个pair,关于pair在这里不展开,可以去百度 for(auto it:mp) cout<< it.first << ":" << it.second <<" "; cout<<endl; return 0; }
还有一些关于map的方法如下:
#include"cstdio"
#include"string" #include"map" using namespace std; map<string,int>mp; int main(){ mp["one"]=1; mp["two"]=2; mp["three"]=3; mp["four"]=4; mp.insert(make_pair("one",1)); //和mp["one"]=1;的作用差不多,区别在于如果mp中的"one"如果已经有值,mp["one"]=1会覆盖掉原有值,而上面这句会插入失败; printf("%d\n",mp.size()); //mp.size()返回mp中有几条记录,这里插入了四条,所以返回为4; mp.erase(mp.begin()); //mp.begin()的作用是返回mp中的第一条记录的迭代器,这里的迭代器类似地址,就像指针; //mp.erase()的作用是删除括号内的记录; //mp.erase()还有其他写法如:mp.erase("three");删除"three"这条记录; //mp.erase(mp.begin(),mp.end());mp.end()返回mp里的最后一条记录的后一个迭代器,mp.erase(mp.begin(),mp.end())相当于从头删到尾,相当于mp.clear(); printf("%d\n",mp.size()); //删掉之后还剩3条记录 mp.clear(); //用于清空mp; printf("%d\n",mp.size()); //可以验证一下,mp已被清空,所以结果为0; return 0; }
- set
set是一个集合,和map内部都是用红黑树写的,所以比较像,只是set只有键,没有值。一开始我不太会写set的时候用map来代替,就把map的值的数据类型设置为bool。因为bool只有true和false,可以用true表示已存入这个键,用false表示没有这个键。另外,它不能用下标查找和插入。
#include "cstdio" #include "set" using namespace std; // 定义 set<int> st; int main() { // 插入 st.insert(3); st.insert(6); st.insert(6); st.insert(1); // 查询是否存在某个键 if (st.count(3)) { puts("Yes"); } else { puts("No"); } if (st.count(6)) { puts("Yes"); } else { puts("No"); } if (st.count(7)) { puts("Yes"); } else { puts("No"); } // 之前往st中插入了3,6,1,没有7;所以结果是Yes Yes No // st的遍历 for (set<int>::iterator it = st.begin(); it != st.end(); it++) { // 这里的it是一个类似指针的东西,所以要加星号 printf("%d ", *it); } // 和mp差不多,st也可以自动排序,而且没有重复值,那种C++ 11版本的遍历方式也是可以的; // 关于clear size erase 等方法和map差不多,就不写了 return 0; }
- queue
这个容器只能访问最早放进来的东西,也就是队首,只有将队首删掉才能访问第二个元素,常用于BFS算法;
#include "cstdio" #include "queue" using namespace std; queue<int> q; int main() { // 依次放入4,2,6 q.push(4); q.push(2); q.push(6); // front 是访问队首的方法,q.front()返回最早放入的也就是4 printf("%d\n", q.front()); // 这个pop用于删除队首,这个时候2就成了队首 q.pop(); printf("%d\n", q.front()); // 求元素个数,一开始放入三个数,4被删除后还剩两个 printf("%d\n", q.size()); // queue的遍历只能通过循环访问并删除 while (!q.empty()) { printf("%d\n", q.front()); q.pop(); } return 0; }
- stack
和queue相似,stack只能访问队尾
#include "cstdio" #include "stack" using namespace std; stack<int> sk; int main() { // 依次放入4,2,6 sk.push(4); sk.push(2); sk.push(6); // top 是访问队尾的方法,sk.top()返回最晚放入的也就是6 printf("%d\n", sk.top()); // 这个pop用于删除队尾,这个时候2就成了队尾 sk.pop(); printf("%d\n", sk.top()); // 求元素个数,一开始放入三个数,6被删除后还剩两个 printf("%d\n", sk.size()); // stack的遍历 while (!sk.empty()) { printf("%d\n", sk.top()); sk.pop(); } return 0; }