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的文字排版严重吐槽.写好的版发表了就变了) 一: ...
随机推荐
-
AD域控制器通过组策略禁止USB设备
问题:域环境下如何禁用USB口设备? 第一种:用传统的办法,在Bios中禁用USB. 第二种: 微软技术支持回答:根据您的需求, Windows识别USB设备主要通过两个文件,一个是Usbstor.p ...
-
2015baidu复赛 矩形面积(包凸 &;&; ps:附quickhull模板)
矩形面积 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
-
centos7 学习1 KDE配置中文
安装kde桌面后没有中文,可以用以下方法配置中文 #yum list kde*chinese 会显示可以安装的包,我的显示如下 kde-l10n-Chinese.noarch -.fc14 @upda ...
-
2013 Multi-University Training Contest 1 3-idiots
解题报告: 记录 A_i 为长度为 i 的树枝的数量,并让 A 对它本身做 FFT,得到任意选两个树枝能得到的各个和的数量.枚举第三边, 计算出所有两边之和大于第三条边的方案数,并把前两条边包含最长边 ...
-
使用GitHub进行团队协作
当进行团队协作完成一个项目时,GitHub是个不错的选择.下面是记录我和朋友做项目的时候协作的方法. 首先下载Github for windows 客户端,http://windows.github. ...
-
POJ1719- Shooting Contest(二分图最大匹配)
题目链接 题意:给定一个矩阵,每列有两个白点,其它都是黑点,如今要求每列选一个白点,使得每一行至少包括一个白点被选中 思路:利用白点所在的位置用行指向列建图,用行去匹配列,最大匹配数假设不等于行数的话 ...
-
iOS常用的第三方库GitHub地址
MJRefresh https://github.com/CoderMJLee/MJRefresh#期待 Facebook-POP https://github.com/facebook/pop /* ...
-
6.28 Windows Serviece
描述: A 软件,已经注册了一个windows服务并启用,现在需要在服务自己的一个类B里增加一个字段,服务的作用是返回一个该类型B的实例 做法 增加字段,替换服务文件,重新注册服务并开启,但是在A软件 ...
-
学号:201621123032 《Java程序设计》第7周学习总结
1:本周学习总结 1.1:思维导图:Java图形界面总结 2:书面作业 2.1: GUI中的事件处理 2.1.1: 写出事件处理模型中最重要的几个关键词 事件:如鼠标单击,滑动,输入汉字等. 事件源: ...
-
Mysql 查询条件中字符串尾部有空格也能匹配上的问题
一.表结构 TABLE person id name 1 你 2 你(一个空格) 3 你(二个空格) 二.查询与结果 select * from person where `name` = ? 无论 ...