文章目录
容器
STL中的容器包括顺序式容器和关联式容器
顺序式容器:记录元素的位置由记录的时间和地点决定
vector
list
deque
queue
priority_queue:
stack
关联式容器:由容器的规则决定
set
multiset
map
multimap
STL使用的基本方式
vector:动态数组
下面以vector来举例使用STL基本方式:
迭代器相当于指针
//定义一个容器,并且指定这个容器存放的类型是int
vector<int>v
//从末尾快速插入元素
v.push_back(1);
v.push_back(2);
v.push_back(3);
//容器提供的迭代器
vector<int>::iterator pBegin = v.begin(); //返回第一个元素的迭代器
vector<int>::iterator pEnd = v.end(); //返回最后一个元素的下一个位置
//用STL定义的算法遍历+自己写的打印函数(回调)
//因为我们是写代码的人,知道我们的要打印的数据是什么类型的
//所以由我们来回调打印
void PrintVector(int v){
cout<<v;
}
for_each(pBegin,pEnd,PrintVector);
常用容器的基本概念和使用
string容器的特性
char*与string的比较:
- char *是一个指针,string是一个类。string封装了char *管理这个字符串,是一个char *型的容器
- string封装了很多实用的成员方法。查找find,拷贝copy,删除delete,替换replace,插入insert。
- 不用考虑内存释放和越界。string管理char*所分配的内存,每一次string的复制、取值都由string类维护,不用担心复制越界和取值越界。
string初始化-拼接-赋值-查找
初始化:
#include<bits/stdc++.h>
using namespace std;
void test(){
string s1; //调用无参结构
string s2(10,'a'); //有参构造
string s3("abcdefg"); //C风格初始化
string s4(s3); //拷贝构造
}
赋值操作:
void test(){
string s1;
string s2("app"); //初始化
cout<<s1<<endl;
s1=s2;
cout<<s1<<endl;
s1='a';
cout<<s1<<endl;
//成员方法assign赋值
s1.assign("jkl");
cout<<s1<<endl;
}
取值操作:
[]越界直接挂,at越界抛异常out_of_range
void test(){
string s1="abcdefg";
//重载[]操作符
for(int i=0;i<s1.size();i++)
cout<<s[i]<<" ";
//成员函数at
for(int i=0;i<s1.size();i++)
cout<<s1.at(i)<<" ";
//用catch(...)接异常
catch(...){
cout<<"越界"<<endl;
}
}
拼接操作:
void test(){
string s1="abcd";
string s2="1111";
s1+="abcd"; //能够+=一个C风格的字符串
s1+=s2; //能够+=一个string类型的字符串
s1+='a'; //能够+=一个字符
cout<<s1<<endl;
运行结果:
abcd111a
//string.append(const string &s)->把字符串s的前n个字符连接到当前字符串结尾
//string.append(const string &s,int pos, int n)->把字符串s中从pos开始的第n个字符串连接到当前字符串结尾
//string.append(int n,char c)->在当前字符串的末尾加n个字符c
string s3="2222";
s2.append(s3) //将s3加到s2的末尾
string s4=s2+s3 //同上,s3添加在s2尾部
cout<<s4<<endl;
运行结果:
111122222222
查找:
find()从前往后找,找str第一次出现的位置
rfind()从后往前找,找str最后出现的位置
void test(){
string s="abcdefghjkl";
int pos = s.find("fg");
cout<<"pos:"<<pos<<endl;
}
返回第一次出现的位置,要查找最后一次位置同理。
运行结果
5
string替换-比较-字串-插入和删除
替换:
void test(){
string s="abcdefg";
s.replace(0,2,"111");
cout<<s<<endl;
}
将0~2位置替换成111。
运行效果:
111cdefg
比较:
void test(){
string s1="abcd";
string s2="abce";
if(s1.compare(s2)==0){
cout<<"相等"<<endl;
}
else cout<<"不相等"<<endl;
}
相等的时候返回零
运行效果:
不相等
截取子串:
void test(){
string s="abcdefg";
string mystr=s.substr(1,3); //截取下标1~3的子串
cout<<mystr<<endl;
}
运行效果
bcd
插入删除:
void test(){
string s="abcdefg";
s.insert(3,"111"); //下标3位置前面插入111
cout<<s<<endl;
s.erase(0,2); //删除0~2的字符串
cout<<s<<endl;
}
运行结果:
abc111defg
c111defg
vector容器特性
push_back()-->从一个数组的尾部添加元素
pop_back()-->从一个数组的尾部删除元素
vector的迭代器:
v.begin() //指向第一个元素
v.end() //指向最后一个元素的下一个位置
vector的反向迭代器:
v.rbegin() //指向第一个元素的前一个位置
v.rend() //指向最后一个元素
虽然有insert()方法插入,但是要将insert()之后的元素向后移,,,,十分的麻烦~~ 因此我们一般选择只在尾部操作
vector构造函数
初始化:
vector<T>v; //采用模板实现类实现,默认初始化为空
vector(v.begin(),v.end()); //将v[begin(),end())区间中的元素拷贝给本身。
vector(n,elem) //将n个elem拷贝给本身
int arr[] = {2,3,4,1,9};
vector<int>v1(arr,arr+sizeof(arr)/sizeof(int)); //用数组初始化
打印
//可以自己写一个算法打印,使用迭代器(相当于指针)
/*定义一个迭代器变量指向 v.begin :
vector<int>::iterator p=v4.begin()
*/
for(vector<int>::iterator p=v.begin();p!=v.end();p++)
cout<<*p<<" ";
cout<<endl;
赋值
void test(){
int arr[] = {2,3,4,1,9};
vector<int>v1(arr,arr+sizeof(arr)/sizeof(int));
vector<int> v2;
v2=v1; //用赋值号操作
vector<int> v3;
v3.assign(v1.begin(),v1.end()); //用成员符号操作
}
交换
void test(){
int arr[] = {2,3,4,1,9};
vector<int>v1(arr,arr+sizeof(arr)/sizeof(int));
int brr[] = {200,300,400,100,900};
vector<int>v2(brr,brr()sizeof()/sizeof(int));
v2.swap(v1)
}
大小操作
size(); //返回容器中元素的个数
empty(); //判断容器是否为空
resize(int num); //重新指定容器的长度为num,若容器变长则默认值填充;若容器变短则末尾超出被剔除。
void test(){
int arr[] = {2,3,4,1,9};
vector<int>v1(arr,arr+sizeof(arr)/sizeof(int));
cout<<"size:"<<v1.size()<<endl;
if(v1.empty())
cout<<"空"<<endl;
else
cout<<"不空"<<endl;
}
运行结果:
5
不空
输入输出与string基本同
都有at和[ ]
插入和删除操作
insert(const pos, int count, ele); //迭代器向指定位置pos插入count个ele
push_back() //尾插
pop_back() //尾删