其实对这些容器,主要有两大类:
总的来说,vector 和 set map 都挺像,支持迭代器访问
关于插入
vector 插入使用push_back() 而,set,map 都是用insert
但是map insert的是一个pair 对
关于删除:
vector 和 map 都是只能通过迭代器定位删除
而set可以直接通过元素定位删除
关于查找:
vector 没有find函数,只能用algorithm的find函数
而set和map都实现的find函数,返回一个迭代器,如果不是end() 说明找到了
小细节:
set和map 都是有序的呢,因为他们是通过红黑树存储的
queue and stack
而queue stack 不支持,基本只有push,pop,front (top)size empty 这几个方法
priority_queue 跟queue差不多,可以实现最大堆,最小堆,多了个方法top()
#include
#include
#include
#include
#include
#include
#include
using namespace std;
bool comp(const int &a,const int &b)
{
// a > b 就调换位置
return a>b;
}
void showv(vector<int> v){
vector<int>::iterator it;
for(it=v.begin();it!=v.end();it++){
cout<<*it<<" ";
}
// 另一种遍历方式
for(int a:v){
cout<<a<<" ";
}
cout<<endl;
}
void use_vector(){
cout<<"----- 元素的添加方式--------"<<endl;
//创建并初始化
vector<int> b(5,-1);
vector<int> v;
// 创建二维vector m[n][d]
vector<vector<int> > m(n, vector<int>(d));
// push_back 从后部添加
for(int i=0;i<5;i++){
v.push_back(i);
}
//也可以通过指定位置添加
v.insert(v.begin()+1,10);
//也可以通过指定区间插入
v.insert(v.end(),b.begin(),b.end());
cout<<"----- 容器的大小-----"<<endl;
int size = v.size(); // 元素的个数
cout<<"size:"<<size<<endl;
// ------ 元素访问 ------
cout<<"first elem:"<<v.front()<<endl;
cout<<"last elem:"<<v.back()<<endl;
// 使用指针访问
vector<int>::iterator it;
it = v.begin();
cout<<"second elem:"<<*(it+1)<<endl;
// 元素查找
// find 函数是algorithm里面的
it = find(v.begin(),v.end(),10);
if(it!=v.end()){
cout<<"found "<<*it<<endl;
}
else{
cout<<"10 not found"<<endl;
}
//vector 的遍历
for(int i=0;i<v.size();i++){
cout<<v[i]<<" ";
}
cout<<endl;
//指针遍历
showv(v);
//反转遍历
reverse(v.begin(),v.end());
showv(v);
cout<<"------- 元素删除 ------"<<endl;
// 只能通过位置指针指示 ,返回指向下一个元素的指针
it = v.erase(v.begin());
cout<<*it<<endl;
//指定区间删除
it = v.erase(v.end()-2,v.end());
//指针遍历
showv(v);
//------ 自定义排序----------
sort(v.begin(),v.end()); // 默认是按升序排列,即从小到大
cout<<"升序"<<endl;
showv(v);
sort(v.begin(),v.end(),comp); // 通过重写排序比较函数,按照降序比较
cout<<"降序"<<endl;
showv(v);
// 元素清空
v.clear();
cout<<"清空后长度:"<<v.size()<<endl;
}
// 队列的使用
void use_queue(){
cout<<"----------添加元素------"<<endl;
//queue q1(5,1);不能这样初始化值了
queue<int> q;
// 只能通过push压入
for(int i=1;i<5;i++){
q.push(i);
}
cout<<"----------访问元素----------"<<endl;
cout<<"first elem:"<<q.front()<<endl;
cout<<"last elem:"<<q.back()<<endl;
//指针访问
//queue是一种FIFO结构,除了最顶出,最低入外,没有任何方法可以存取其他元素,
//所以不允许有遍历行为。
//强行遍历
int size = q.size();
for(int i=0;i<size;i++){
int num = q.front(); // 返回第一个元素
cout<<num<<" ";
q.pop(); // 不反回任何值
q.push(num);
}
cout<<endl;
// 为空判断
cout<<"is empty:"<<q.empty()<<endl;
// 删除只能为pop
//不支持索引遍历
/*
for(int i=0;i
}
/*
定义:priority_queue
Type 就是数据类型,Container 就是容器类型(Container必须是用数组实现的容器,
比如vector,deque等等,但不能用 list。STL里面默认用的是vector),
Functional 就是比较的方式,当需要用自定义的数据类型时才需要传入这三个参数,使
用基本数据类型时,只需要传入数据类型,默认是大顶堆
*/
struct student{
string name;
int age;
student(string name1,int g){
name=name1;age=g;
}
//重载比较函数,最大堆
// 最大堆重载< 号, 对应于priority_queue, less>;
// 最小堆重载> 号, 对应于priority_queue, greater>;
bool operator < (const student& s) const {
return age<s.age; // 小于就换,故最大堆
}
};
void use_priority_queue(){
//最小堆
// 第一个参数是存储的数据类型,第二个是采用容器,一般用vector
// 第三个是比较函数,默认是less
priority_queue<int,vector<int>,greater<int> > minq;
// 最大堆
priority_queue<int,vector<int>,less<int> > maxq;
// ------ 添加元素----
for(int i=0;i<5;i++){
maxq.push(i);
}
// -----遍历元素-----
while(!maxq.empty()){
cout<<maxq.top()<<" ";
maxq.pop();
}
cout<<endl;
// pair 的使用,先比较第一个值,再比较第二个值
priority_queue<pair<int, int> > a;
pair<int, int> b(1, 2);
pair<int, int> c(1, 3);
pair<int, int> d(2, 5);
a.push(d);
a.push(c);
a.push(b);
while (!a.empty())
{
cout << a.top().first << ' ' << a.top().second << '\n';
a.pop();
}
// 自定义结构体
priority_queue<student> s;
s.push(student("lhj",19));
s.push(student("scc",18));
while(!s.empty()){
cout<<s.top().name<<" "<<s.top().age<<endl;
s.pop();
}
}
// stack 的使用
/*
empty() 堆栈为空则返回真
pop() 移除栈顶元素
push() 在栈顶增加元素
size() 返回栈中元素数目
top() 返回栈顶元素
*/
void use_stack(){
stack<int> s;
// 添加元素
for(int i=0;i<5;i++){
s.push(i);
}
//size
int size = s.size();
cout<<"size is :"<<size<<endl;
for(int i=0;i<size;i++){
int num = s.top();
cout<<num<<" ";
s.pop();
}
cout<<endl;
}
// ------------顺序容器包括vector、deque、list、forward_list、array、string
//------------ 关联容器 map - set
// 集合的使用
/*
在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。
set中元素的值不能直接被改变。
set内部采用的是一种非常高效的平衡检索二叉树:红黑树,也称为RB树(Red-Black Tree)
set 有两个特点:
-排好序的
-元素无重复
*/
void use_set(){
cout<<"------元素插入----"<<endl;
//按照升序存储
set<int> s;
for(int i=5;i>=0;i--){
s.insert(i);
}
cout<<"-------元素访问------"<<endl;
cout<<"first elem:"<<*s.begin()<<endl;
cout<<"last elem:"<<*(--s.end())<<endl;
//元素遍历
set<int>::iterator it;
for(it=s.begin();it!=s.end();++it){
cout<<*it<<" ";
}
cout<<endl;
cout<<"------元素统计与查找-------"<<endl;
cout<<"size:"<<s.size()<<endl;
cout<<"count 1:"<<s.count(1)<<endl;
//返回一个指向被查找到元素的迭代器
it = s.find(4);
if(it!=s.end()){
cout<<"found "<<*it<<endl;
}else{
cout<<"not found"<<endl;
}
cout<<"---------元素删除---------"<<endl;
//erase()–删除集合中的元素,指定元素删除
s.erase(1);
cout<<"count 1:"<<s.count(1)<<endl;
//清空
s.clear();
cout<<"is empty:"<<s.empty()<<endl;
}
// map的使用
//map是STL的一个关联容器,它提供一对一的hash。 (key,value) 可以为任何数据类型
void use_map(){
map<int,string> m;
cout<<"--------元素插入-----"<<endl;
//第一种,通过pair插入,会检查key唯一性
m.insert(pair<int,string>(1,"lhj"));
m.insert(pair<int,string>(1,"solicucu")); //无效
//第二种,通过数组的形式插入,有同样的key,就会覆盖value
m[2]="scc";
//对于第一种如何确认是否插入成功呢
//定义一个返回类型pair
pair<map<int,string>::iterator,bool> p;
p = m.insert(pair<int,string>(1,"solicucu")); //无效
cout<<"insert is success:"<<p.second<<endl;
cout<<"-------元素访问------"<<endl;
cout<<"数组形式:"<<m[1]<<endl;
//map 也是有一定的顺序的,升序所以可以迭代访问
cout<<"first elem:"<<(*m.begin()).second<<endl;
//元素遍历
map<int,string>::iterator it;
for(it=m.begin();it!=m.end();it++){
cout<<(*it).second<<endl;
}
//元素查找,key is param
it = m.find(2);
if(it!=m.end()){
cout<<"found "<<(*it).second<<endl;
}
else{
cout<<"not found"<<endl;
}
// 算键值,有啥意思
cout<<"count:"<<m.count(1)<<endl;
cout<<"--------删除元素----------"<<endl;
// 删除 ,通过迭代器删除
m.erase(it);
cout<<"rest size:"<<m.size()<<endl;
m.clear(); //清空
cout<<"is empty:"<<m.empty()<<endl;
}
//容器的使用
int main(){
// use_vector();
// use_queue();
// use_priority_queue();
// use_stack();
// use_set();
use_map();
}
#include
#include
#include
#include
#include
using namespace std;
int main(){
// 字典遍历
map<int, int> count;
count[1]=2;
count[2]=3;
for(auto item:count){
cout<<item.first<<" "<<item.second<<endl;
}
set<int> s1 = {1,2,3};
set<int> s2 = {2,3,4};
vector<int> v;
// 求交集 可以是任意地迭代器,set, vector 都可
// 另外需要一个容器装结果 v, 通过最后一个参数 back_inserter 插入
set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(), back_inserter(v));
for(int a:v){
cout<<a<<" ";
}
cout<<endl;
v.clear();
// 求并集
set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), back_inserter(v));
for(int a:v){
cout<<a<<" ";
}
cout<<endl;
v.clear();
//差集, 把A中有B地元素给剔除
set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(), std::back_inserter(v));
for(int a:v){
cout<<a<<" ";
}
/*
1 2
2 3
2 3
1 2 3 4
1
*/
}
#include
#include
#include
#include
using namespace std;
int main(){
string s;
vector<string> v;
while(cin>>s){
v.push_back(s);
if(getchar()=='\n'){
sort(v.begin(),v.end());
for(string ss:v){
cout<<ss<<" ";
}
cout<<endl;
v.clear();
}
}
}
根据特定分隔符划分字符串, 用stringstream 对象和 getline()
#include
#include
#include
#include
using namespace std;
int main(){
string s,item;
vector<string> v;
while(cin>>s){
stringstream ss(s);
// ss:stringstream 对象,item:分割的字符,','分割字符
while(getline(ss, item, ',')){
v.push_back(item);
}
sort(v.begin(),v.end());
for(int i=0;i<v.size()-1;i++){
cout<<v[i]<<",";
}
cout<<v[v.size()-1]<<endl;
v.clear();
}
}
string s = to_string(x);
string s2="1,2,3,4";
// 根据逗号分割
istringstream ss(s2);
string t;
vector<int> v;
while(getline(ss, t, ',')){
cout<<t<<" ";
v.push_back(stoi(t));
}
for(int a:v) cout<<a<<" ";