STL(standard template library)
STL的全称是standard template libarry,标准模板库,即是C++中诸多的基本的,常用的数据结构,数据算法。这里对STL容器做一些展开记录,STL容器主要包括6种,即vector(非定长数组),string(字符串),queue(队列)/deque(双端队列),stack(栈),list(双向列表),set(集合)/multiset(多元集合),map(映射)
vector(非定常数组)
使用vector容器,要首先包括头文件 #include<vector>
创建数组
(不知道数组多长) ,以创建int类型s数组为例,vector<int> s;
(知道数组多长),以创建int类型,数组长度为3为例,vector<int> s(3);
数组赋值
如果在vector<int> s(3);的情况下使用s.push_back(0);不使用预先分配的内存,数组长度加1
按顺序插入,vector<int> s;(此时s数组长度为0)以插入int类型,1,2,3为例:
s.push_back(1);s.push_back(2);s.push_back(3);
直接赋值:在创建vector<int> s(3);(此时数组长度为3)的情况下,可以赋值s[0]=1;s[1]=2;s[2]=3;
数组输出
在不溢出的情况下,在vector<int> s和vector<int> s(3)的情况下,可以正常输出(与一般数组使用无异)
cout<<s[0]<<" "<<s[1]<<" "<<s[2]<<endl;
迭代器使用(几乎适用所有容器)
vector<int>::iterator sbegin=s.begin();//容器第一个元素指针指向地址
vector<int>::iterator send=s.end(); //容器最后一个元素指针指向地址,这里一般用来以下使用(可按顺序输出s内储存数据
方法1:(在定义了sbegin和send的基础上)
while(sbegin!=send){
cout<<*sbegin<<endl;
sbegin++;
}
方法2:(有点像一般for循环,不需要定义sbegin和send)适用于很多容器,改一下容器名称即可list<int> ,deque<int>,
for (vector<int>::iterator it = s.begin(); it != s.end(); it++) {
cout << *it << endl;
}
方法3:利用STL提供算法
#include<algorithm>
...
void printmx(int val) {
cout << val << endl;
}
...
int main(){
...
for_each(s.begin(), s.end(),printmx);//
return 0;
}
capacity函数和size函数的使用
s.capacity()是指开辟的s的数组的容量,s.size()是指函数中使用的长度。两者一般不相等
(pop_back函数使用)数组删除:
s.pop_back();//删除尾部的一个数据
insert插入函数和erase删除函数的使用
s.insert(s.begin(), 100);//在数组最前面插入100
s.insert(s.begin(), 2, 10);//在数组最前面插入2个10
s.erase(s.begin());//删除数组最前面的数
resize函数使用(重新限制数组长度,减小数组长度,会丢失数据)
s.resize(3);
clear函数的使用(清空数组)
s.clear();//清空数组
at函数使用(s.at(i)=s[i])
cout << s.at(0) << " " << s[0] << endl;//两者使用输出结果一样
sort排序函数使用
sort(s.begin(),s.end());//从小到大排序
swap函数和reserve函数
当vector数组一通操作后,发现数组容量大于数组长度,可以使用swap函数收缩数组容量;
当觉得vector数组多次操作都要重新计算数组容量,浪费时间,可以使用reverse函数为数组预先设定一个足够的容量
vector<int>(s).swap(s);//收缩数组容量
s.reserve(10);//预留数组容量
list(双端列表容器)
创建列表(push_back,push_front插入,pop_back,pop_front删除)
list<int> s;
list<int> s1;
list<int> s2;
list<int> s4;
s.push_back(1);//list可以双端插入,可以从前端插入,可以从后端插入
s.push_front(2);
s1.push_back(3);
s1.push_front(4);
s2.assign(s1.begin(), s1.end());//可以插入其他列表的区间
s4.assign(5, 10);//可以通过assign函数插入5个10
list<int> s5(s4);//可以直接赋值其他的双端列表中的值
s.pop_back();//list可以双端删除,可以从前端删除,可以从后端删除
s.pop_front();
swap函数
s.swap(s5);//交换s和s5中的值
resize函数
s.resize(2);//将s的长度限制为2,长度减小会丢失数据
insert函数
list<int>::iterator itbegin = s.begin();
s.insert(itbegin,5);
//两者方式等同,在开头插入5
s.insert(s.begin(), 5);
remove函数
s.remove(10);//删除列表中所有的10
erase函数
s.erase(++itbegin);//删除itbegin+1后的数字
sort函数
s.sort();//排序,从小到大排序
索引(front(),back()函数)
list<int>::iterator itbegin=s.begin();
cout << s.front() << s.back() << endl;//可以通过s.front(),s.back()获取list前后端的值
string(字符串容器)
在使用string类型时,要在头文件中包括#include<string>
创建string
string s="";string s="abchd";string s="c";
string s = "s";
string s1("abcd");
string s2(s1);
string s3(10, 'a'); //创建10个a的字符串“aaaaaaaaaa”
size函数,字符串的长度
cout << s.size() << " " << s.length() << endl;//两者都返回字符串s的长度
assign函数使用
s1.assign(s1,0, 2);//s1输出结果ab,从0为开始保留2位
s1.assign("abcd", 2);//s1输出结果ab,从0开始,保留2位
s1.assign(s1, 2);//s1输出结果位cd,从2开始,保留到结尾
append函数使用
s1.append("STLgame", 3, 4);//输出结果:abgame 从STLganme位置3,保留4位,添加到s1字符串后
s1.append("game");输出结果 STLgamegame 直接在字符串后面添加game;
s1=s1+"game";
find函数使用
int t=s1.find("game");//返回game第一次出现的位置2
replace函数使用
s1.replace(2, 4, "flower");//输出结果:abflowergame 将s1从位置2开始的4个字符替换为字符串flower
compare函数的使用(直接比较两个字符串是否相等)
s1.compare(s1)//返回值为int类型,相等返回0,
at函数使用(用来读取字符串)
cout<<s1.at(0)<<" "<<s1[0];//输出结果一致
insert函数和erase函数使用
s1.insert(1, "f");//在位置1插入f,其余字符向后移位
s1.erase(3, 6);//删除从位置3开始的6个字母
substr截取字符串字串
string sson = s1.substr(3, 4);//sson等于从s1的位置3开始截取的4个字符
queue(队列)/deque(双端队列)
使用queue,要包括头文件#include<queue>,队列 先进先出 只能头端进,尾端出
使用deque,要包括头文件#include<deque> 相当于一个两端都可以进出
创建队列
queue<int> s;
deque<int> s1;
队列操作(push函数,push_front函数,push_back函数,pop函数,pop_front函数,pop_back()函数)
s.push(1);//queue容器插入,只能从前端插入
s.push(2);
s.push(3);
//结果是1 2 3
s.pop();//queue容器删除,只能从后端删除
//-----------------------------------
s1.push_front(1);//deque容器插入,可以从前端插入,也可以从后端插入
s1.push_front(2);
s1.push_back(3);
结果是
2 1 3
s1.pop_back();//从后端删除第一个元素
s1.pop_front();//从前端删除第一个元素
queue不可以通过索引得到容器内的值,deque可以通过索引得到值,也可以通过迭代器得到容器中的值
queue遍历输出如下
while (!s.empty()) {
cout << s.front() << endl;
s.pop();
}
deque遍历输出如下
//通过迭代器得到deque中的值
for (deque<int>::iterator it = s1.begin(); it != s1.end(); it++) {
cout << *it << endl;
}
//通过索引得到deque中的值
for (int i = 0; i < s1.size(); i++) {
cout << s1[i] << " ";
}
队列长度(size函数)
没有容量这个概念
cout << s1.size() << " " << s.size() << endl;//deque和queue通用
deque插入和删除(insert函数和erase函数)
s1.insert(s1.begin(),10);//在开头插入一个10,其他位后移
s1.insert(s1.begin(), 2, 5);//在开头插入两个5,其他位后移
s1.insert(s1.begin(), s1.begin(), s1.end());//在开头插入s1区间的开头到结束的数据
s1.erase(s1.begin());//删除开头那个数据
s1.erase(s1.begin()+1, s1.end());//删除s1区间开头加1到结尾的数据
deque的at函数 双端数组可以直接索引
cout << s1.at(1) << " " << s1[1] << endl;//两者输出结果相同
deque<int>::iterator itbegin=s1.begin();//返回指向s1第一个元素的迭代器
deque<int>::iterator itend=s1.end();//返回指向s1最后一个元素的迭代器
deque排序(sort函数)
sort(s1.begin(), s1.end());//从小到大排序
stack容器(栈)先进后出
创建stack容器
首先要包括头文件#include<stack>
stack<int> s;
stack<int> s1;
stack函数顶端插入,删除(push函数,pop函数)
s1.emplace(89);//函数插入,只能从顶端插入
s.push(1);
s.push(3);
s.emplace(4);
s.pop();//函数删除,只能从顶端删除
swap函数
s.swap(s1);交换s和s1中的值
size,empty函数
s.size();//判断栈s的长度
s.empty();//判断栈s是否为空
stack遍历函数
while (!s1.empty()) {
cout << s1.top() << " ";
s1.pop();
}
set/multiset容器
使用前,要包括#include<set>头文件,set在插入后会自动排序,并且去重,multiset可以插入重复数据,也可以排序
创建set/multiser容器(insert函数)
multiset<int> gg;
gg.insert(100);
gg.insert(100);
gg.insert(98);//gg输出是98 100
set<char> s;
set<int> s1;
s.insert('b');
s.insert('a');
s1.insert(100);
s1.insert(100);
s1.insert(98);//s1输出是98 100
set<int> s2(s1);
set<int> s3;
s3 = s2;
swap函数
s1.swap(s3);//交换s1和s3