忙完四级啦,知识点光写了一直没整理,最近整出来。(我就是现学现编的一枚小萌新,不是啥大佬就是分享记录一下这一个月的学习过程。)
今天我们来康康算法题常用的stl标准模板库。
这个stl呀,就是c++帮你封装好的模板,里边什么定义呀函数呀功能呀直接拿来用就好,感谢stl帮你省去手撸的麻烦。
模板有vector,stack , queue , list , set , map
说说常用的模板:vector,queue,set,map
一、vector
vector这玩意儿挺厉害的,可以称它叫“动态数组”,动态动态就是长度可以变化的。废话少说不讲原理直接上架应用。
首先,我们要用就必须先创建一个vector,创建格式:
vector<type>name;
vector叫动态数组嘛就还是一系列元素排在一起,这个元素也就是type可以是各种类型,如int,char,string,struct,pair等等甚至可以嵌套stl类,反正就是个类型都可以。
vector的初始化:以int型vector举例
vector<int>a; 默认初始化,a为空
vector<int>a(100); a有100个值为0的元素
vector<int>a(100,6); a有100个值为6的元素
常用操作有:
赋值 a.push_back(number); 在尾部添加值为number的元素
元素个数 int size=a.size(); 返回元素个数
是否为空 bool isEmpty=a.empty(); 判断是否为空,空返回true
打印 cout<<a[0]<<endl; 打印第一个元素
插入 a.insert(a.begin()+i,k); 在第i个元素前面插入k
尾部插入 a.push_back(8); 尾部插入值为8的元素
尾部插入 a.insert(a.end(),10,5); 尾部插入10个值为5的元素
删除尾部 a.pop_back(); 删除末尾元素
删除区间 a.erase(a.begin()+i,a.begin()+j); 删除区间[i,j-1]的元素
删除元素 a.erase(a.begin()+n); 删除a[n];
调整大小 a.resize(n); 数组大小变为n
清空 a.clear(); 清空
翻转 reverse(a.begin(),a.end()); 翻转顺序
排序 sort(a.begin(),a.end()); 从小到大排序
二、queue
队列是基本的数据结构之一,特点是“先进先出”,例如排队,先进队列的先得到服务
队列的有关操作:
queue<Type>q; //定义队列,Type为数据类型,例如int,float,char等
q.push(item); //把item放进队列
q.front(); //返回队首元素,但不会删除
q.pop(); //删除队首元素
q.back(); //返回队尾元素
q.size(); //返回元素个数
q.empty(); //检查队列是否为空
双端队列容器:deque
deque 容器也擅长在序列尾部添加或删除元素(时间复杂度为O(1)),而不擅长在序列中间添加或删除元素。
与vector相比,多了一个push_front() 在序列的头部添加一个元素。
pop_front() 移除容器头部的元素。
别的一样;
二点五、迭代器
迭代器这玩意儿看起来很高级很高大上,事实上就起到一个指向标的作用,类似指针,用来访问模板类中的元素,指向他使得可以使用他。stack,queue不支持迭代器,别的模板类都支持迭代器。vector有迭代器但是咱可以直接用下标进行随机访问嘛,一般不用迭代器。像list,set,map用的多。
迭代器的创建如vector的迭代器://语法方面vector换成别的也行,格式就这样
vector<type>::iterator it;
这个it是一个迭代器的名字,当然也可以用别的名字 。*it就是这个迭代器指向的元素,就跟指针一样嘛。it用起来就像指针一样,it可自增,不进行大于小于比较,只用相等不相等。it 指向元素有成员的话就和指针一样用->,像 it->first,is->second.
容器都有成员begin和end,其中begin成员复制返回指向第一个元素的迭代器,而end成员返回指向容器尾元素的下一个位置的迭代器,它是一个不存在的元素位置。类似于字符串末尾的‘\0'
//所以如果你想遍历容器(vector)元素的话,可以这样写:用it < vector.end()是不合法的!!!
for( it = vector.begin(); it != vector.end(); it++ )
cout<<*it<<endl;
//vector换成set,map什么的也差不多
三、set
set就是集合,stl的set用二叉搜索树实现,集合中的每个元素只出现一次,并且是排好序的(插入后会自动排序)。
访问元素的时间复杂度是O(log2n),非常高效。
set的有关操作:
set<Type>A; //定义
A.insert(item); //把item放进set
A.erase(item); //删除元素item
A.clear(); //清空set
A.empty(); //判断是否为空
A.size(); //返回元素个数
A.find(k); //返回一个迭代器,指向键值k
A.lower_bound(k); //返回一个迭代器,指向键值不小于k的第一个元素
A.upper_bound(k); //返回一个迭代器,指向键值大于k的第一个元素
三点五、pair
首先我们了解一个新的类型pair, pair类型包含了两个数据值,通常有以下的一些定义和初始化的一些方法:
//T1,T2为类型名
pair<T1, T2> p; //定义了一个空的pair对象p
pair<T1, T2> p(v1, v2); //定义了包含初始值为v1和v2的pair对象p
make_pair(v1, v2) //以v1和v2值创建的一个新的pair对象
pair的第一个成员是first,第二个成员是second,一定就这俩成员。指向这俩成员的时候就是p.first,p.second这样子。
举个栗子:
pair<int, string> p1(0, "Hello");
printf("%d, %s\n", p1.first, p1.second.c_str());
pair<int, string> p2 = make_pair(1, "World");
printf("%d, %s\n", p2.first, p2.second.c_str());
四、map
map是stl中的一种关联容器,键值对容器,提供key(键)-value(值)方式的储存,!每个关键字在map中出现一次!!!
map内部是有序的,从小到大(指键从小到大,按字典序顺序);
map中的迭代器可以用 -> (间接成员运算符)//因为map对象有两个成员 first 和 second;
map的定义:
map<key,value>mapname;
注意!!!!!!!!!!:打印时一定是first和second分别打印,无法直接打印整体(类似结构体)
1、插入:
用insert插入pair数据:
如:
map<int,string>student;
student.insert(pair<int,string>(1,"student_one"));
student.insert(pair<int,string>(2,"student_two"));
student.insert(pair<int,string>(3,"student_three"));
map<int,string>::iterator it;
for(it=student.begin();it!=student.end();it++)
cout<<it->first<<" "<<it->second<<endl;
用数组方式插入数据://数组内的表达式为关键字,如map<string,int>时,用该方式插入:student["name"]=15;
如:
map<int,string>student;
student[1] = "student_one";
student[3] = "student_three";
student[2] = "student_two";
map<int,string>::iterator it;
for(it=student.begin();it!=student.end();it++)
cout<<it->first<<" "<<it->second<<endl;
2、查找:
函数原型:iterator find (const key_type& k);
//关键字查询,找到则返回指向该关键字的迭代器,否则返回指向end的迭代器;
3、删除:
函数原型:iterator erase( iterator pos );
// 删除迭代器指向位置的键值对,并返回一个指向下一元素的迭代器
函数原型:iterator erase( const_iterator first, const_iterator last );
// 删除一定范围内的元素,并返回一个指向下一元素的迭代器
函数原型:size_t erase( const key_type& key );
// 根据Key来进行删除, 返回删除的元素数量,在map里结果非0即1,因为每个关键字只出现一次
函数原型:void clear();
// 清空map,清空后的size为0
4、交换
函数原型:void swap(map&other);
//就是两个map内容互换;
5、容量
函数原型:bool empty();
// 查询map是否为空
函数原型:size_t size();
// 查询map中键值对的数量
函数原型:size_t max_size();
// 查询map所能包含的最大键值对数量,和系统和应用库有关。
// 此外,这并不意味着用户一定可以存这么多,很可能还没达到就已经开辟内存失败了
函数原型:size_t count( const Key& key ) const;
// 查询关键字为key的元素的个数,在map里结果非0即1