目录
一、容器种类
1.顺序容器:各元素之间有顺序关系的线性表
vector(向量)、list(列表)、deque(队列)
2.关联容器:非线性树状结构 默认插入按升序排列
set(映射)、map(集合)(无重复)
multimap(多重集合)、multiset(多重映射)
3.容器适配器:使一种不同的行为类似于另一事物的行为的一种机制
stack(栈)、queue(队列)、priority_queue(优先队列)
二、容器的适用场景
三、不同容器的使用方法(待补充)
1.string
string对象会自动忽略开头的空白(既空格、换行符、制表符等),并从第一个真正的字符开始读入,直到遇到下一处空白。
①定义与获取
//定义与初始化
string s="abc";
string s1(s); //拷贝定义
string s2(10,'a') //创建10个a的字符串
//字符串数组(操作可直接当作数组)
string s[N];//在字符串数组的每一个元素中存放一个字符串,而不是一个字符
int n;cin>>n;
for(int i=0;i<n;i++) cin>>s[i];
cout<<s[0]<<" "<<s[1][2]<<endl;
s[1].erase(1,1);
cout<<s[1]<<" "<<s[1][2]<<endl;
//用getline读取一整行(直到换行符才停止读取)
string s1;
getline(cin, s1);
string s1;
while(getline(cin, s1))
cout << s1 << endl;
②操作方法
//string赋值
string str1 = "hello cpp"
string str2 = str1;
//string拼接
string s1 = "I";
s1 += " love China!";
string s2 = "But I don't like";
string s3 = s1 + s2;
s3.append(" Japan");
//查找和替换
s.find("lanqiao"); //第一次出现:若找到返回下标,否则返回-1
s.rfind("l"); //最后一次出现
s.append("forever"); //末尾进行插入,等同+运算符
s.replace(1, 3, "1111"); //从下标1开始顺数3位数替换位1111
//字符串比较
if(s1==s2) //直接比较
if(s1=="lanqiao")
//字符串存取
int len=s.size(); //大小
int lenn=s.length();
//插入与删除
s.insert(1,"xxx"); //从下标1插入xxx
s.erase(1); //删除下标为1的元素
s.erase(1,3); //删除下标为[1,3)的元素
//大小写转换
tolower(c)和toupper(c) //c为一个字符
//string的排序
sort(s.begin(),s.end());
//截取字串
string str=s.substr(1,3); //获取某段字符串
//逆置
s.reverse(s.begin(),s.end())
//类型转换
int n=stoi(s); //string转int
string s=to_string(s); //int转string
③遍历方法:和数组一样
2.vector
vector数据结构和数组非常相似,但数组是静态空间,而vector可以动态扩展
①定义与初始化
vector<int> vec1; //默认初始化,vec1为空
vector<int> vec2(vec1); //使用vec1初始化vec2
vector<int> vec3(vec1.begin(),vec1.end());//使用vec1初始化vec2
vector<int> vec4(10); //10个值为0的元素
vector<int> vec5(10,4); //10个值为4的元素
vector<string> vec6(10,"null"); //10个值为null的元素
vector<string> vec7(10,"hello"); //10个值为hello的元素
②操作方法
vec1.push_back(100); //添加元素
a.insert(a.begin()+1,5); //在a的第1个元素(从第0个算起)的位置插入数值5
a.assign(b.begin(), b.begin()+3); //b为向量,将b的0~2个元素构成的向量赋给a
a.assign(4,2); //是a只含4个元素,且每个元素为2
int size = vec1.size(); //元素个数
bool isEmpty = vec1.empty(); //判断是否为空
vec1.find(5) //(!=vec1.end())返回迭代器的一个值
vec1.insert(vec1.end(),5,3); //从vec1.back位置插入5个值为3的元素
vec1.pop_back(); //删除末尾元素
vec1.erase(vec1.begin(),vec1.end());//删除之间的元素,其他元素前移
a.swap(b); //b为向量,将a中的元素和b中的元素进行整体性交换
cout<<(vec1==vec2)?true:false; //判断是否相等==、!=、>=、<=...
vector<int>::iterator iter = vec1.begin(); //获取迭代器首地址
vector<int>::const_iterator c_iter = vec1.begin(); //获取const类型迭代器
vec1.clear(); //清空元素
③遍历方法
// 下标法(vector的特有访问方法,一般容器只能通过迭代器访问)
int length = vec1.size();
for(int i=0;i<length;i++)
cout<<vec1[i];
cout<<endl<<endl;
// 迭代器
vector< int >::const_iterator iterator = vec1.begin();
for (;iterator != vec1.end();iterator++)
cout<<*iterator;
④vector排序
//自定义排序,按身高降序,身高相同时则按名字升序排列
vector<string>res;
sort(res.begin(),res.end(),[&](const string&a,const string&b)->bool{
return map[a]==map[b]?a<b:map[a]>map[b];
});
bool cmp( const pair< vector<int>,int >& x,const pair< vector<int>,int >& y )
{
return ( x.second == y.second ) ? ( x.first < y.first ) : ( x.second > y.second ) ;
}
sort( vp.begin(),vp.end(),cmp);
3.set
集合,它同map一样,底层使用红黑树实现,插入删除操作时仅仅移动指针即可,不涉及内存的移动和拷贝,所以效率比较高,在set中不会存在重复的元素。
①定义与初始化
set<int> s;
②操作方法
set2.insert(i); //插入
set2.find(5); //(!=set2.end())返回迭代器的一个值
set2.clear(); //集合清除
int len=set2.size(); //集合大小
while (!set1.empty()) //判空
{
//获取头部
set<string>::iterator it = set1.begin();
//打印头部元素
cout << *it << endl;
//从头部删除元素
set1.erase(set1.begin());
}
③遍历方法
for (set<int>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
4.map
一对一映射,无重复元素,通过键值对的方式来存储和访问数据的,底层是通过红黑树来实现的。
①定义与初始化
//第一种:用insert函数插入pair数据:
map<int, string> mp;
mp.insert(pair<int, string>(1, "first"));
mp.insert(pair<int, string>(2, "second"));
//第二种:用insert函数插入value_type数据:
mp.insert(map<int, string>::value_type(3, "first"));
mp.insert(map<int, string>::value_type(4, "second"));
//第三种:用数组的方式直接赋值:
mp[5] = "first";
mp[6] = "second";
//迭代器遍历
map<int, string>::iterator it;
for (it = mp.begin(); it != mp.end(); it++)
cout << it->first << "->" <<it->second << endl;
//map的嵌套用法
map<int,map<int,string>> mp1;
mp1[1][1] = "张三";
mp1[1][2] = "李四";
mp1[1][3] = "王五";
for (map<int, map<int, string>>::iterator it = mp1.begin(); it != mp1.end(); it++)
{
for (map<int, string>::iterator in_it = it->second.begin(); in_it != it->second.end(); in_it++)
{
cout << it->first << "年级" << in_it->first << "号同学:" << in_it->second << endl;
}
}
②操作方法
//添加元素
map1[3] = "Saniya";
//元素个数
map1.size();
//返回mp中key的出现次数
mp.count(key)
//判断空
map1.empty();
//清空所有元素
map1.clear();
//插入元素
map1.insert(map<int,string>::value_type(2,"Diyabi"));
map1.insert(pair<int,string>(1,"Siqinsini"));
map1.insert(make_pair<int,string>(4,"V5"));
//根据key取得value,key不能修改
string str = map1[3];
//删除元素(整个键值对key,value)
map<string, int> students;
students["李白"] = 346;
students["李商隐"] = 113;
students["杜牧"] = 156;
students.erase("李白"); //删除"李白"这个key
students.erase(std::begin(students)); //删除第一个元素
//find:如果mp容器中存在按key索引的元素,则返回指向该元素的迭代器。否则则返回超出末端迭器。
map<string, int>::iterator iter = students.find("杜牧");
//删除"杜牧"对应的value
students.erase(iter);
③遍历方法
for(map<int,string>::iterator iter = mp.begin();iter!=mp.end();iter++)
{
int keyk = iter->first;
string valuev = iter->second;
}
4.queue
队列,实现了一个先进先出的容器。
①定义与初始化
queue<int> q;
用q.front()和q.back()访问队首和队尾
②操作方法
//添加元素
q.push(x);
//出队
q.pop();
//判断空
q.empty();
//元素个数
q.size()
③一般不用于查询遍历
四、STL的案例
1.PTA L2-3 清点代码库
map_vector vector排序
#include<bits/stdc++.h> using namespace std; map<vector<int>,int> mp;//储存不重复功能和个数 vector<pair<vector<int>,int>> vp;//用于排序 vector<int> v;//储存功能 bool cmp(const pair<vector<int>,int>&x,const pair<vector<int>,int>&y){ return (x.second==y.second)?(x.first<y.first):(x.second>y.second); } int main() { int n,m,x; cin>>n>>m; vp.clear(); while(n--){ v.clear(); for(int i=0;i<m;i++){ cin>>x;v.push_back(x); } mp[v]++; } vp.insert(vp.end(),mp.begin(),mp.end()); sort(vp.begin(),vp.end(),cmp);//排序 cout<<vp.size()<<endl; for(int i=0;i<vp.size();i++){ cout<<vp[i].second; v=vp[i].first; for(int j=0;j<v.size();j++) cout<<" "<<v[j]; cout<<endl; } return 0; }