STL基础学习STL中的容器解析代码展示例题分析帮助你学STL.docx
- 文档编号:7518675
- 上传时间:2023-01-24
- 格式:DOCX
- 页数:19
- 大小:25.23KB
STL基础学习STL中的容器解析代码展示例题分析帮助你学STL.docx
《STL基础学习STL中的容器解析代码展示例题分析帮助你学STL.docx》由会员分享,可在线阅读,更多相关《STL基础学习STL中的容器解析代码展示例题分析帮助你学STL.docx(19页珍藏版)》请在冰豆网上搜索。
STL基础学习STL中的容器解析代码展示例题分析帮助你学STL
STL就是StandardTemplateLibrary(C++标准模板库),下面是关于STL中的各种内容
STL中的几个基本概念:
1.容器:
可容纳各种数据类型的数据结构。
可以用于存放各种类型的数据(基本类型的变量,对象等)的数据结构。
容器分为三大类:
(1)顺序容器
vector:
后部插入/删除,直接访问deque:
前/后部插入/删除,直接访问list:
双向链表,任意位置插入/删除
1)vector头文件
实际上就是个动态数组。
随机存取任何元素都能在常数时间完成。
在尾端增删元素具有较佳的性能。
2)deque头文件
也是个动态数组,随机存取任何元素都能在常数时间完成(但性能次于vector)。
在两端增删元素具有较佳的性能。
3)list头文件
双向链表,在任何位置增删元素都能在常数时间完成。
不支持随机存取。
上述三种容器称为顺序容器,是因为元素的插入位置同元素的值无关。
(2)关联容器
set:
快速查找,无重复元素multiset:
快速查找,可有重复元素map:
一对一映射,无重复元素,基于关键字查找multimap:
一对一映射,可有重复元素,基于关键字查找,前2者合称为第一类容器
关联式容器内的元素是排序的,插入任何元素,都按相应的排序准则来确定其位置。
关联式容器的特点是在查找时具有非常好的性能。
1)set/multiset:
头文件
set即集合。
set中不允许相同元素,multiset中允许存在相同的元素。
2)map/multimap:
头文件
map与set的不同在于map中存放的是成对的key/value。
并根据key对元素进行排序,可快速地根据key来检索元素
map同multimap的不同在于是否允许多个元素有相同的key值。
上述4种容器通常以平衡二叉树方式实现,插入和检索的时间都是O(logN)
(3)容器适配器
stack:
LIFOqueue:
FIFOpriority_queue:
优先级高的元素先出
对象被插入容器中时,被插入的是对象的一个复制品。
许多算法,比如排序,查找,要求对容器中的元素进行比较,所以,放入容器的对象所属的类,还应该实现==和<运算符。
1)stack:
头文件
栈。
是项的有限序列,并满足序列中被删除、检索和修改的项只能是最近插入序列的项。
即按照后进先出的原则
2)queue:
头文件
队列。
插入只可以在尾部进行,删除、检索和修改只允许从头部进行。
按照先进先出的原则。
3)priority_queue:
头文件
优先级队列。
最高优先级元素总是第一个出列
所有标准库容器共有的成员函数:
相当于按词典顺序比较两个容器大小的运算符:
=,<,<=,>,>=,==,!
=
empty:
判断容器中是否有元素
max_size:
容器中最多能装多少元素
size:
容器中元素个数
swap:
交换两个容器的内容
只在第一类容器中的函数:
begin返回指向容器中第一个元素的迭代器
end返回指向容器中最后一个元素后面的位置的迭代器
rbegin返回指向容器中最后一个元素的迭代器
rend返回指向容器中第一个元素前面的位置的迭代器
erase从容器中删除一个或几个元素
clear从容器中删除所有元素
2.迭代器:
可依次存取容器中元素的东西
用于指向第一类容器中的元素。
有const和非const两种。
通过迭代器可以读取它指向的元素,通过非const迭代器还能修改其指向的元素。
迭代器用法和指针类似。
定义一个容器类的迭代器的方法可以是:
容器类名:
:
iterator变量名;
或:
容器类名:
:
const_iterator变量名;
访问一个迭代器指向的元素:
*迭代器变量名
迭代器上可以执行++操作,以指向容器中的下一个元素。
如果迭代器到达了容器中的最后一个元素的后面,则迭代器变成past-the-end值。
使用一个past-the-end值的迭代器来访问对象是非法的,就好像使用NULL或未初始化的指针一样。
算法:
用来操作容器中的元素的函数模板。
例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象。
函数本身与他们操作的数据的结构和类型无关,因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用。
比如,数组intarray[100]就是个容器,而int*类型的指针变量就可以作为迭代器,可以为这个容器编写一个排序的算法,以下是各种算法:
#include
#include
usingnamespacestd;
intmain(){
vector
v.push_back
(1);
v.push_back
(2);
v.push_back(3);
v.push_back(4);
vector
:
const_iteratori;//常量迭代器
for(i=v.begin();i!
=v.end();i++)
cout<<*i<<",";
cout< vector : reverse_iteratorr;//反向迭代器 for(r=v.rbegin();r! =v.rend();r++) cout<<*r<<","; cout< vector : iteratorj;//非常量迭代器 for(j=v.begin();j! =v.end();j++) *j=100; for(i=v.begin();i! =v.end();i++) cout<<*i<<","; } 输出结果: 1,2,3,4, 4,3,2,1, 100,100,100,100, STL中的迭代器按功能由弱到强分为5种: 1.输入: Inputiterators提供对数据的只读访问。 1.输出: Outputiterators提供对数据的只写访问 2.正向: Forwarditerators提供读写操作,并能一次一个地向前推进迭代器。 3.双向: Bidirectionaliterators提供读写操作,并能一次一个地向前和向后移动。 4.随机访问: Randomaccessiterators提供读写操作,并能在数据中随机移动。 编号大的迭代器拥有编号小的迭代器的所有功能,能当作编号小的迭代器使用。 不同迭代器所能进行的操作(功能): 所有迭代器: ++p,p++ 输入迭代器: *p,p=p1,p==p1,p! =p1 输出迭代器: *p,p=p1 正向迭代器: 上面全部 双向迭代器: 上面全部,--p,p--, 随机访问迭代器: 上面全部,以及: p+=i,p-=i, p+i: 返回指向p后面的第i个元素的迭代器 p-i: 返回指向p前面的第i个元素的迭代器 p[i]: p后面的第i个元素的引用 p 容器所支持的迭代器类别: 容器迭代器类别 vector随机 deque随机 list双向 set/multiset双向 map/multimap双向 stack不支持迭代器 queue不支持迭代器 priority_queue不支持迭代器 例如,vector的迭代器是随机迭代器,所以遍历vector可以有以下几种做法: vector vector : value_typei;//等效于写inti;(P687) for(i=0;i cout< vector : const_iteratorii; for(ii=v.begin();ii! =v.end();ii++) cout<<*ii; //间隔一个输出: ii=v.begin(); while(ii cout<<*ii; ii=ii+2; } 而list的迭代器是双向迭代器,所以以下代码可以: list list : const_iteratorii; for(ii=v.begin();ii! =v.end();ii++) cout<<*ii; 以下代码则不行: for(ii=v.begin();ii cout<<*ii; //双向迭代器不支持< for(inti=0;i cout< 例子: #include #include #include usingnamespacestd; main(){ intarray[10]={10,20,30,40}; vector v.push_back (1);v.push_back (2); v.push_back(3);v.push_back(4); vector : iteratorp; p=find(v.begin(),v.end(),3); if(p! =v.end()) cout<<*p< p=find(v.begin(),v.end(),9); if(p==v.end()) cout<<"notfound"< p=find(v.begin()+1,v.end()-2,1); if(p! =v.end()) cout<<*p< int*pp=find(array,array+4,20); cout<<*pp< } 输出: 3 notfound 3 20 例: intmain(){inti; inta[5]={1,2,3,4,5};vector cout< for(i=0;i v.at(4)=100; for(i=0;i cout< cout< vector v2.insert(v2.begin()+2,13);//在begin()+2位置插入13 for(i=0;i cout< return0; } 输出: 5 0,1,2,3,100, 1,2,13,3,4,5, 例: intmain(){ constintSIZE=5; inta[SIZE]={1,2,3,4,5}; vector try{ v.at(100)=7; } catch(out_of_rangee){ cout< } cout< v.erase(v.begin()); ostream_iterator copy(v.begin(),v.end(),output); v.erase(v.begin(),v.end());//等效于v.clear(); if(v.empty()) cout<<"empty"< v.insert(v.begin(),a,a+SIZE); copy(v.begin(),v.end(),output); } //输出: invalidvector 1,5 2*3*4*5*empty 1*2*3*4*5* 关于ostream_iterator,istream_iterator的例子 intmain(){ istream_iterator intn1,n2; n1=*inputInt;//读入n1 inputInt++; n2=*inputInt;//读入n2 cout< ostream_iterator *outputInt=n1+n2;cout< inta[5]={1,2,3,4,5}; copy(a,a+5,outputInt);//输出整个数组 return0; } 程序运行后输入7890敲回车,则输出结果为: 78,90 168 12345 例'; #include #include usingnamespacestd; intmain(){ typedefset constintSIZE=5; doublea[SIZE]={2.1,4.2,9.5,2.1,3.7}; double_setdoubleSet(a,a+SIZE); ostream_iterator cout<<"1)"; copy(doubleSet.begin(),doubleSet.end(),output); cout< pair : const_iterator,bool>p; p=doubleSet.insert(9.5); if(p.second) cout<<"2)"<<*(p.first)<<"inserted"< else cout<<"2)"<<*(p.first)<<"notinserted"< return0;} 输出: 1)2.13.74.29.5 2)9.5notinserted #include #include usingnamespacestd; ostream&operator<<(ostream&o,constpair { o<<"("< returno; } intmain(){ typedefmap mmidpairs; cout<<"1)"< pairs.insert(mmid: : value_type(15,2.7)); pairs.insert(make_pair(15,99.3));//make_pair生成pair对象 cout<<"2)"< pairs.insert(mmid: : value_type(20,9.3)); mmid: : iteratori; cout<<"3)"; for(i=pairs.begin();i! =pairs.end();i++) cout<<*i<<","; cout< cout<<"4)"; intn=pairs[40];//如果没有关键字为40的元素,则插入一个 for(i=pairs.begin();i! =pairs.end();i++) cout<<*i<<","; cout< cout<<"5)"; pairs[15]=6.28;//把关键字为15的元素值改成6.28 for(i=pairs.begin();i! =pairs.end();i++) cout<<*i<<","; return0; } 输出: 1)0 2)1 3)(15,2.7),(20,9.3), 4)(15,2.7),(20,9.3),(40,0), 5)(15,6.28),(20,9.3),(40,0), 如何用程序用来统计一篇英文文章中单词出现的频率(为简单起见,假定依次从键盘输入该文章) #include >#include usingnamespacestd; intmain(){ map stringword; while(cin>>word) ++wordCount[word]; for(map : iteratorit=wordCount.begin();it! =wordCount.end();++it) cout<<"Word: "<<(*it).first<<"\tCount: "<<(*it).second< return0;} 例: #include #include usingnamespacestd; intmain(){ priority_queue priorities.push(3.2); priorities.push(9.8); priorities.push(5.4); while(! priorities.empty()){ cout< } return0; } //输出结果: 9.85.43.2 例: intmain(){ constintSIZE=10; inta1[]={2,8,1,50,3,100,8,9,10,2}; vector ostream_iterator vector : iteratorlocation; location=find(v.begin(),v.end(),10); if(location! =v.end()){ cout< } sort(v.begin(),v.end()); if(binary_search(v.begin(),v.end(),9)) cout< else cout< return0; } 输出: (无sort语句) 1)8 2)3 3)9notfound 输出: (有sort语句) 1)8 2)3 3)9found STL就是StandardTemplateLibrary(C++标准模板库),下面是关于STL中的各种内容 STL中的几个基本概念: 1.容器: 可容纳各种数据类型的数据结构。 可以用于存放各种类型的数据(基本类型的变量,对象等)的数据结构。 容器分为三大类: (1)顺序容器 vector: 后部插入/删除,直接访问deque: 前/后部插入/删除,直接访问list: 双向链表,任意位置插入/删除 1)vector头文件 实际上就是个动态数组。 随机存取任何元素都能在常数时间完成。 在尾端增删元素具有较佳的性能。 2)deque头文件 也是个动态数组,随机存取任何元素都能在常数时间完成(但性能次于vector)。 在两端增删元素具有较佳的性能。 3)list头文件 双向链表,在任何位置增删元素都能在常数时间完成。 不支持随机存取。 上述三种容器称为顺序容器,是因为元素的插入位置同元素的值无关。 (2)关联容器 set: 快速查找,无重复元素multiset: 快速查找,可有重复元素map: 一对一映射,无重复元素,基于关键字查找multimap: 一对一映射,可有重复元素,基于关键字查找,前2者合称为第一类容器 关联式容器内的元素是排序的,插入任何元素,都按相应的排序准则来确定其位置。 关联式容器的特点是在查找时具有非常好的性能。 1)set/multiset: 头文件 set即集合。 set中不允许相同元素,multiset中允许存在相同的元素。 2)map/multimap: 头文件 map与set的不同在于map中存放的是成对的key/value。 并根据key对元素进行排序,可快速地根据key来检索元素 map同multimap的不同在于是否允许多个元素有相同的key值。 上述4种容器通常以平衡二叉树方式实现,插入和检索的时间都是O(logN) (3)容器适配器 stack: LIFOqueue: FIFOpriority_queue: 优先级高的元素先出 对象被插入容器中时,被插入的是对象的一个复制品。 许多算法,比如排序,查找,要求对容器中的元素进行比较,所以,放入容器的对象所属的类,还应该实现==和<运算符。 1)stack: 头文件 栈。 是项的有限序列,并满足序列中被删除、检索和修改的项只能是最近插入序列的项
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- STL 基础 学习 中的 容器 解析 代码 展示 例题 分析 帮助