C++ STL基本容器的使用(vector、list、deque、map、stack、queue)
1、关联容器和顺序容器
C++中有两种类型的容器:顺序容器和关联容器,顺序容器主要有:vector、list、deque等。关联容器主要有map和set。如下图:
1、vector基本使用
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std; //利用模版进行输出
template <typename T>
void print(vector<T> a)
{
//输出方法1
for(auto i:a)
{
cout<<i<<'\t';
}
cout<<endl;
//输出方法2
typename vector<T>::iterator it;//前面要加typename,要不会出错
for(it=a.begin();it!=a.end();it++)
{
cout<<*it<<'\t';
}
cout<<endl;
//输出方法3,这里只是想说这样也可以输出
cout<<a[]<<'\t'<<a[]<<'\t'<<a[]<<'\t'<<a[]<<'\t'<<a[]<<endl;
cout<<"********************"<<endl;
} int main()
{
/*vector初始化对象*/
vector<int> v1;//v1是一个空的vector,潜在的元素是int类型,执行时,默认初始化
v1={,,,,};
print(v1); vector<int> v2(v1);//相当于vector<int> v2=v1
print(v2); vector<char> v3(,'a');//v3中含有5个a字符
print(v3); vector<string> v4{"aa","ss","dd","ff","gg"};//v4赋值
print(v4); vector<float> v5();//出事化v5,为5个0.0
v5[]=1.1;
// v5[6]=8.8; vector可以利用下标访问,但是不能使用下标添加元素
print(v5); /*-------------------------------------------------------------------------------*/ /*vector操作*/
vector<string> v6;
if(v6.empty())//vector是否为空
{
cout<<"------"<<"v6 is empty"<<"-------"<<endl;
}
string s="qwe";
for(int i=;i<;i++)
{
v6.push_back(s);//末尾添加一个元素
}
v6.pop_back();//末尾删除一个
v6.push_back("");
print(v6);
cout<<"------"<<"v6的长度为:"<<v6.size()<<"------"<<endl;
v6=v4;//拷贝v4中的元素赋值到v6中
if(v6==v4)
{
cout<<"------"<<"v6==v4"<<"------"<<endl;
} /*-------------------------------------------------------------------------------*/ /*vector常用操作*/
vector<int> array={,,,,,,,,,};
array.erase(remove(array.begin(),array.end(),),array.end());//需添加头文件algorithm
/*remove函数使用:
*remove(始地址,终地址,需要移除的元素),返回是被替换的数第一个数的地址,比如本题vector
*原始数组为:[1,6,2,6,3,6,4,6,5,6],使用remove函数后为[1,2,3,4,5,6,4,6,5,6],
*返回的地址为位置5上(0开始)的6的地址,如下输出数字5.
cout<<*(remove(array.begin(),array.end(),6)-1)<<endl;*/ /*删除6的另一种方法
vector<int>::iterator it1;
it1=array.begin();
for(it1=array.begin();it1!=array.end();it1++)
{
if(6==*it1)
{
array.erase(it1);//删除掉it1时,it1会指向下一个数,也就是6,然后再自加会指向下一个6,也就是邻接的6是删除不掉的
it1--;//加上这一句就不会出错
}
}*/
print(array); vector< vector<int> > intVV;//vector实现二维数组
vector<int> intV;
int i,j;
for(i=;i<;++i){
intV.clear();
for(j=;j<;++j)
intV.push_back(i*+j);
intVV.push_back(intV);
} for(i=;i<;++i){
for(j=;j<;++j)
cout<<intVV[i][j]<<'\t';
cout<<endl;
}
return ;
}
2、list基本使用
Lst1.assign() 给list赋值
Lst1.back() 返回最后一个元素
Lst1.begin() 返回指向第一个元素的迭代器
Lst1.clear() 删除所有元素
Lst1.empty() 如果list是空的则返回true
Lst1.end() 返回末尾的迭代器
Lst1.erase() 删除一个元素
Lst1.front() 返回第一个元素
Lst1.insert() 插入一个元素到list中
Lst1.pop_back() 删除最后一个元素
Lst1.pop_front() 删除第一个元素
Lst1.push_back() 在list的末尾添加一个元素
Lst1.push_front() 在list的头部添加一个元素
Lst1.rbegin() 返回指向第一个元素的逆向迭代器
Lst1.remove() 从list删除元素
Lst1.rend() 指向list末尾的逆向迭代器
Lst1.reverse() 把list的元素倒转
Lst1.size() 返回list中的元素个数
Lst1.sort() 给list排序
Lst1.unique() 删除list中重复的元素
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <list>
using namespace std; //利用模版进行输出
template <typename T>
void print(list<T> a)
{
//输出方法1
for(auto i:a)
{
cout<<i<<'\t';
}
cout<<endl;
//输出方法2
typename list<T>::iterator it;//前面要加typename,要不会出错
for(it=a.begin();it!=a.end();it++)
{
cout<<*it<<'\t';
}
cout<<endl;
cout<<"********************"<<endl;
} int main()
{
/*list初始化*/
list<int> l1;//定义一个空的list
list<int> l2(,);//定以一个长度为5的list
print(l2);
list<char> l3={'a','b','c','d'};
print(l3);
list<char> l4(l3);//相当于l4=l3
print(l4);
list<char> l5(l3.begin(),l3.end());//同上
print(l5);
list<char> l6=l5;//同上
print(l6); /*----------------------------------------------------------------------*/ /*常用操作*/
list<int> array={,,,,,,};
print(array);
array.sort();
print(array);
array.reverse();
print(array);
cout<<"返回第一个元素:"<<array.front()<<endl;
cout<<"返回最后一个元素:"<<array.back()<<endl;
cout<<"返回第一个元素迭代器:"<<*(array.begin())<<endl;
cout<<"返回最后一个元素迭代器:"<<*(--array.end())<<endl;
cout<<"返回第一个元素的逆向迭代器:"<<*(array.rbegin())<<endl;
cout<<"返回最后一个元素的逆向迭代器:"<<*(array.rend())<<endl; list<int> array1;
array1.assign(array.begin(),array.end());//给list赋值给array1
array1.pop_front();//删除第一个元素
array1.pop_back();//删除最后一个元素
print(array1);
array1.clear();//删除所有元素
if(array1.empty())//判断lsit是否为空
{
cout<<"array1 is empty"<<endl;
}
array1.assign(,);//array1={1,1,1,1,1,1}
array1.push_front();//在list头插入元素
array1.push_back();//在list尾插入元素
print(array1);
array1.erase(array1.begin());//擦除list第一个数
array1.erase(--array1.end());//擦除list最后一个数
print(array1);
cout<<"array1的长度为:"<<array1.size()<<endl;//array1的长度
array1.insert(++array1.begin(),,);//从位置1开始插入3个9
print(array1);
array1.remove();//移除list中的所有元素9
print(array1);
array1.unique();//移除list中重复元素
print(array1);
return ;
}
3、deque基本使用
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <deque>
using namespace std; //利用模版进行输出
template <typename T>
void print(deque<T> a)
{
//输出方法1
for(auto i:a)
{
cout<<i<<'\t';
}
cout<<endl;
//输出方法2
typename deque<T>::iterator it;//前面要加typename,要不会出错
for(it=a.begin();it!=a.end();it++)
{
cout<<*it<<'\t';
}
cout<<endl;
//输出方法3,这里只是想说这样也可以输出
cout<<a[]<<'\t'<<a[]<<'\t'<<a[]<<'\t'<<a[]<<'\t'<<a[]<<endl;
cout<<"********************"<<endl;
} int main()
{
/*deque初始化操作*/
deque<int> d1();
for(int i=;i<;i++)
{
d1[i]=i;
}
print(d1);
deque<string> d2(,"abc");//d2中存在6个abc
print(d2);
deque<string> d3(d2);//初始化d3=d2
print(d3); /*----------------------------------------------------------------------*/ /*deque基本操作*/
deque<int> array(,);
array.push_front();//头部插入
array.push_back();//尾部插入
array.insert(array.begin()+,);//在位置1插入9
print(array);
array.pop_front();//头部删除
array.pop_back();//尾部删除
print(array);
cout<<"头元素:"<<array.front()<<'\t'<<"尾元素:"<<array.back()<<'\t'<<"大小:"<<array.size()<<endl;
array.erase(++array.begin(),--array.end());//删除该区间内的元素
print(array);
array.clear();
if(array.empty())
{
cout<<"array is empty"<<endl;
}
return ; }
4、set基本使用
begin()--返回指向第一个元素的迭代器
clear()--清除所有元素
count()--返回某个值元素的个数
empty()--如果集合为空,返回true
end()--返回指向最后一个元素的迭代器
equal_range()--返回集合中与给定值相等的上下限的两个迭代器
erase()--删除集合中的元素
find()--返回一个指向被查找到元素的迭代器
get_allocator()--返回集合的分配器
insert()--在集合中插入元素
lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器
key_comp()--返回一个用于元素间值比较的函数
max_size()--返回集合能容纳的元素的最大限值
rbegin()--返回指向集合中最后一个元素的反向迭代器
rend()--返回指向集合中第一个元素的反向迭代器
size()--集合中元素的数目
swap()--交换两个集合变量
upper_bound()--返回大于某个值元素的迭代器
value_comp()--返回一个用于比较元素间的值的函数
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <set>
using namespace std; //利用模版进行输出
template <typename T>
void print(set<T> a)
{
//输出方法1
for(auto i:a)
{
cout<<i<<'\t';
}
cout<<endl;
//输出方法2
typename set<T>::iterator it;//前面要加typename,要不会出错
for(it=a.begin();it!=a.end();it++)
{
cout<<*it<<'\t';
}
cout<<endl;
cout<<"********************"<<endl;
} int main()
{
/*set初始化操作*/
set<int> s={,,,,};//注意set里面不会存在重复的数
print(s);
set<int> s1(s);//s1=s;
print(s1); /*----------------------------------------------------------------------*/ /*set基本操作*/
s1.insert();//插入一个元素
int a[]={,,,};
s1.insert(a,a+);//将a的前3个元素插入set
print(s1);
cout<<"s1的长度:"<<s1.size()<<'\t'
<<"s1的第一个元素:"<<*s1.begin()<<'\t'
<<"s1的最后一个元素:"<<*--s1.end()<<'\t'<<'\n'//注意最后位置要减1
<<"s1的最后一个元素:"<<*s1.rbegin()<<'\t'
<<"s1的第一个元素:"<<*--s1.rend()<<'\t'//注意最后位置要减1
<<endl; cout<<"s1中11出现的次数是 :"<<s.count()<<endl;//因为set保证元素唯一,所以可以判断数据的存在性 cout<<"s1中第一个大于等于17的数是:"<<*s1.lower_bound()<<endl;
cout<<"s1中第一个大于17的数是:"<<*s1.upper_bound()<<endl; pair<set<int>::const_iterator,set<int>::const_iterator> p;
p = s.equal_range();
cout<<"第一个大于等于14的数是 :"<<*p.first<<'\t'
<<"第一个大于14的数是 : "<<*p.second<<endl; set<string> s2={"as","ad","af","ag","ah"};
print(s2);
s2.erase(s2.begin());//删除第一个元素
s2.erase("ad");//删除对应元素
print(s2);
s2.erase(++s2.begin(),--s2.end());//删除该区间内元素
print(s2);
set<string>::iterator iter=s2.find("as");//找到 as 并返回该元素的位置
cout<<*iter<<endl;
s2.clear();
if(s2.empty())
{
cout<<"s2 is empty"<<endl;
} return ; }
5、栈、队列的使用
栈:
empty() 堆栈为空则返回真
pop() 移除栈顶元素
push() 在栈顶增加元素
size() 返回栈中元素数目
top() 返回栈顶元素
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <stack>
#include <deque>
#include <vector>
#include <list>
using namespace std; //利用模版进行输出
template <typename T>
void print(stack<T> a)
{
while(!a.empty())
{
cout<<a.top()<<'\t';
a.pop();//元素出栈
}
} int main()
{
/*stack的操作*/
stack<int> s;
for(int i=;i<;i++)
{
s.push(i);//元素进栈
}
cout<<"s的大小为:"<<s.size()<<endl;
cout<<"s为:\n";
print(s);
cout<<endl; deque<int> d(,);
stack<int> s1(d);//将deque赋值给stack
cout<<"s1为:\n";
print(s1);
cout<<endl; vector<string> v={"aa","ss","dd","ff"};
stack<string,vector<string> >s2(v);//将vector赋值给stack
cout<<"s2为:\n";
while(!s2.empty())
{
cout<<s2.top()<<'\t';
s2.pop();//元素出栈
}
cout<<endl; list<char> c={'a','s','d','f','g','h'};
stack<char,list<char> > s3(c);//将list赋值给stack
cout<<"s3为:\n";
while(!s3.empty())
{
cout<<s3.top()<<'\t';
s3.pop();//元素出栈
}
cout<<endl;
return ; }
队列和栈的基本操作差不多
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <deque>
#include <vector>
#include <list>
using namespace std; //利用模版进行输出
template <typename T>
void print(queue<T> a)
{
while(!a.empty())
{
cout<<a.front()<<'\t';
a.pop();//元素出栈
}
} int main()
{
/*queue的操作*/
queue<int> s;
for(int i=;i<;i++)
{
s.push(i);//元素进栈
}
cout<<"s的大小为:"<<s.size()<<endl;
print(s);
cout<<endl; deque<int> d(,);
queue<int> s1(d);//将deque赋值给stack
cout<<"s1为:\n";
print(s1);
cout<<endl; vector<string> v={"aa","ss","dd","ff","hh"};
queue<string,vector<string> >s2(v);//将vector赋值给stack
cout<<s2.front()<<'\t'<<s2.back()<<endl; list<char> c={'a','s','d','f','g','h'};
queue<char,list<char> > s3(c);//将list赋值给stack
cout<<"s3为:\n";
while(!s3.empty())
{
cout<<s3.front()<<'\t';
s3.pop();//元素出栈
}
cout<<endl;
return ; }
6、Map的基本使用
Map主要用于资料一对一映射(one-to-one)的情况,map内部的实现自建一颗红黑树,这颗树具有对数据自动排序的功能。
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <map>
#include <deque>
#include <vector>
#include <list>
using namespace std; //利用模版进行输出
template <typename T>
void print(map<T,T> a)
{
cout<<"输出的方法1:\n";
typename map<T, T>::iterator it;
for(it = a.begin(); it != a.end(); it++)
cout<<it->first<<' '<<it->second<<endl;
cout<<"输出的方法2:\n";
typename map<T, T>::reverse_iterator iter;
for(iter = a.rbegin(); iter != a.rend(); iter++)
cout<<iter->first<<' '<<iter->second<<endl;
} int main()
{
/*map的赋值操作*/
map<string, string> m;
//赋值的方法1
m.insert(map<string, string>::value_type ("", "s1"));
m.insert(map<string, string>::value_type ("", "s2"));
m.insert(map<string, string>::value_type ("", "s3"));
//赋值方法2
m.insert(pair<string,string>("","s4"));
m.insert(pair<string,string>("","s5"));
m.insert(pair<string,string>("","s6"));
print(m);
cout<<"--------------------------------------------"<<endl; map<int, string> m2;
//赋值的方法3
m2[]="one";
m2[]="two";
m2[]="three";
// print(m2); 这里两个类型不一样不能进行模版输出
map<int, string>::iterator iter2;
for(iter2 = m2.begin(); iter2 != m2.end(); iter2++)
cout<<iter2->first<<' '<<iter2->second<<endl;
for(int i=;i<=;i++)//这种输出必须保证map中前一个数为int类型
{
cout<<m2[i]<<endl;
}
cout<<"--------------------------------------------"<<endl; /*判断插入是否成功*/
map<char,char> m3;
m3.insert(map<char,char>::value_type('','a'));
m3.insert(map<char,char>::value_type('','b'));
m3.insert(map<char,char>::value_type('','c'));
m3.insert(map<char,char>::value_type('','e'));
m3.insert(map<char,char>::value_type('','f'));
m3.insert(map<char,char>::value_type('','g'));
pair<map<char,char>::iterator,bool> insert_pair;//接收判断插入的成功与否 insert_pair=m3.insert(pair<char,char>('','d'));
if(insert_pair.second) cout<<"插入成功!"<<endl;
else cout<<"插入失败!"<<endl; insert_pair=m3.insert(pair<char,char>('','d'));
if(insert_pair.second) cout<<"插入成功!"<<endl;
else cout<<"插入失败!"<<endl;
print(m3);
cout<<"--------------------------------------------"<<endl;
cout<<"m3的大小为:"<<m3.size()<<endl;
cout<<"--------------------------------------------"<<endl; /*数据查找*/
//
map<char,char>::iterator iter=m3.find('');
if(iter!=m3.end()) cout<<"2对应的值为"<<iter->second<<endl;
//
int n=m3.count('');
if(n) cout<<"2存在于map中"<<endl;
else cout<<"2不存在于map中"<<endl;
//
iter=m3.lower_bound('');
cout<<"2对应的值为:"<<iter->second<<endl;
iter=m3.upper_bound('');
cout<<"2后面的键对应的值为:"<<iter->second<<endl;
cout<<"--------------------------------------------"<<endl; /*数据删除*/
//
iter=m3.find('');
m3.erase(iter);
//
n=m3.erase('');
if(n) cout<<"3以及对应的value删除成功"<<endl;
else cout<<"3以及对应的value删除失败"<<endl;
//
m3.erase(++m3.begin(),--m3.end());
print(m3); }
容器选择的基本原则:
1、除非你有很多的理由选择其它的容器,否则应该用vector。
2、如果你的程序有很多小的元素,且空间的额外开销很重要,则不要使用list。
3、如果程序要求随机访问元素,则应该使用vector或则deque。
4、如果程序需要在容器的中间插入删除元素,应该使用list。
5、如果程序需要在容器的头尾位置插入或删除元素,但不会在中间位置进行插入或者删除操作,则使用deque。
6、如果程序只有在读取输入时才需要在容器中间位置插入元素,随后需要随机访问元素则:
首先,确定是否真的需要在容器中间位置添加元素,当处理输入数据时,通常可以很容易地向vector追加数据,然后调用标准库的sort函数来重排容器中的元素,从而避免在中间位置添加元素。
如果必须在中间位置插入元素,考虑在输入阶段使用list,一旦输入完成,将list中的内容拷贝到一个vector中。
注:如果不确定应该使用哪种容器,那么可以在程序中只使用vector和list公共的操作:使用迭代器,不使用下表操作,避免随机访问。这样。在必要的时候选择vector或list都很方便。
C++ STL基本容器的使用(vector、list、deque、map、stack、queue)的更多相关文章
- 顺序容器删除元素 vector list deque
#include <iostream>#include <list>#include <algorithm>#include <string> usin ...
- vector、deque、stack、queue、list以及set的使用
注意:以下测试案例都要加上相应的头文件,必要时要加上algorithm文件. 1.vector 连续存储结构,每个元素在内存上是连续的:支持高效的随机访问和在尾端插入/删除操作,但其他位置的插入/删除 ...
- STL List容器
转载http://www.cnblogs.com/fangyukuan/archive/2010/09/21/1832364.html 各个容器有很多的相似性.先学好一个,其它的就好办了.先从基础开始 ...
- STL之容器适配器queue的实现框架
说明:本文仅供学习交流,转载请标明出处,欢迎转载! 上篇文章STL之容器适配器stack的实现框架已经介绍了STL是怎样借助基础容器实现一种经常使用的数据结构stack (栈),本文介绍下第二种STL ...
- 第十篇:顺序容器vector,deque,list的选用规则
前言 常见的顺序容器主要有三种 - vector,deque,list.它们实现的功能相差不大,那么实际开发中该如何进行选择呢?本文将为你解答这个问题. 分析 由于这三种容器实现的数据结构原型不同(v ...
- 顺序容器vector,deque,list的选用规则
前言 常见的顺序容器主要有三种 - vector,deque,list.它们实现的功能相差不大,那么实际开发中该如何进行选择呢?本文将为你解答这个问题. 分析 由于这三种容器实现的数据结构原型不同(v ...
- STL顺序容器用法自我总结
顺序容器类型:vector.deque.list.forward_list.string.array. queue(单向队列)底层也是用deque(双端队列)实现的 a.swap(b); swap(a ...
- STL学习系列二:Vector容器
1.Vector容器简介 vector是将元素置于一个动态数组中加以管理的容器. vector可以随机存取元素(支持索引值直接存取, 用[]操作符或at()方法,这个等下会详讲). vector尾部添 ...
- STL顺序容器【vector】【deque】【list】
我们都知道,stl在集装箱船分为两类,订购集装箱和相关的容器. 顺序容器有三种即动态数组vector,双端队列deque,以及链表list (对csdn的文字排版严重吐槽.写好的版发表了就变了) 一: ...
随机推荐
- 修正剑桥模型预测-用python3.4
下面是预测结果: #!/usr/bin/env python # -*- coding:utf-8 -*- # __author__ = "blzhu" ""& ...
- 安卓修改开机logo
这里我们是在ubuntu下进行操作我是用root用户登陆的,首先安装netpbm库 执行:apt-get install netpbm 对于Android系统最开始表现logo是在内核当中,所以首先我 ...
- .net Json JavaScriptSerializer JsonHelper类
结合.net 的JavaScriptSerializer 类实现Json数据处理 调用1: Model.Users m = BLL.UsersBLL.GetUserById(Convert.ToInt ...
- JSP动作元素<jsp:include>和<jsp:param>的搭配使用
最近开发项目中广告头的优化:引入了<jsp:include page="XX.jsp"></jsp:include> 当<jsp:include> ...
- 20155326 实验四 Android程序设计实验报告
20155326 实验四 Android程序设计实验报告 实验内容 1.基于Android Studio开发简单的Android应用并部署测试; 2.了解Android.组件.布局管理器的使用: 3. ...
- java基础-day8
第08天 常用API 今日内容介绍 u API概述 u Scanner类与String类 u StringBuilder类 第1章 API概述 1.1 API概念 API(Applica ...
- oj错误之char型超出范围
在oj时遇到一个题 题目本身并不是很难,但在一个数据时出了错,刚开始一直没想通是哪里出了错 下面为源代码 #include <bits/stdc++.h> using namespace ...
- uva10905同一思路的两种做法,前一种WA,后一种AC
这道题应该算一道普通的排序吧,实际上就是另一种形式地比大小,自己最开始是用int型存,后来觉着不行,改用long,结果还是WA,这是第一个程序. 第二个程序是改用string处理,确实比int方便很多 ...
- [Chrome_Error] (failed) net::ERR_INCOMPLETE_CHUNKED_ENCODING 与 nginx 502 bad gateway
Chrome 浏览器出现这个错误,还出现 nginx 502 bad gateway . 查看 nginx 的 error.log : 2015/12/18 14:34:44 [error] 1448 ...
- NFS Server宕机后,NFS Client主机上df命令挂死
方法1: 使用root用户:Oracle@NDMCDB05:~> su -Password: NDMCDB05:~ # cat /etc/mtab /dev/sda2 / reiserfs rw ...