标准模板类(STL)(二),具体容器简介
作者:互联网
(二)容器的具体介绍
A、顺序式容器
1、vector
该标准容器是一个定义在 namespace std 中的模板,该模板的原型声明在头文件 <vector> 中。它的数据结构很像一个数组,所以与其他容器相比,vector 能非常方便和高效访问单个元素。因此,在 vector 中提供随机访问循环子。
说明:实际上就是个动态数组。随机存取任何元素都能在常数时间完成。在尾端增删元素具有较佳的性能。例1:
int main()
{ int i;
int a[5] = {1,2,3,4,5 };
vector<int> v(5);
cout << v.end()-v.begin() << endl;
for( i = 0;i < v.size();i ++ ) v[i] = i;
v.at(4) = 100;
for( i = 0;i < v.size();i ++ )
cout << v[i] << "," ;
cout << endl;
vector<int> v2(a,a+5); //构造函数
v2.insert( v2.begin() + 2, 13 ); //在begin()+2位置插入 13
for( i = 0;i < v2.size();i ++ )
cout << v2[i] << "," ;
return 0;
}
输出:
5
0,1,2,3,100,
1,2,13,3,4,5,
例2:
int main() {
const int SIZE = 5;
int a[SIZE] = {1,2,3,4,5 };
vector<int> v (a,a+5); //构造函数
try {
v.at(100) = 7;
}
catch( out_of_range e) {
cout << e.what() << endl;
}
cout << v.front() << “,” << v.back() << endl;
v.erase(v.begin());
ostream_iterator<int> output(cout ,“*");
copy (v.begin(),v.end(),output);
v.erase( v.begin(),v.end()); //等效于 v.clear();
if( v.empty ())
cout << "empty" << endl;
v.insert (v.begin(),a,a+SIZE);
copy (v.begin(),v.end(),output);
}
// 输出:
invalid vector<T> subscript
1,5
2*3*4*5*empty
1*2*3*4*5*
ostream_iterator<int> output(cout ,“*");//定义了一个 ostream_iterator 对象,可以通过cout输出以 * 分隔的一个个整数
copy (v.begin(),v.end(),output);//导致v的内容在 cout上输出
copy 函数模板(算法):
template<class InIt, class OutIt>
OutIt copy(InIt first, InIt last, OutIt x); //本函数对每个在区间[0, last - first)中的N执行一次 *(x+N) = * ( first + N) ,返回 x + N
对于copy (v.begin(),v.end(),output);
first 和 last 的类型是 vector<int>::const_iterator,output 的类型是 ostream_iterator<int>
例3
#include "iostream"
#include "vector"
#include "algorithm"
using namespace std;
int main()
{
istream_iterator<int>inputInt(cin);
int n1,n2;
n1=*inputInt;
inputInt++;
n2=*inputInt;
cout<<n1<<" "<<n2<<endl;
ostream_iterator<int>outputInt(cout);
*outputInt=n1+n2;
cout<<endl;
int a[5]={1,2,3,4,5};
copy(a,a+5,outputInt);
return 1;
}
输出结果为:
78,90
168
12345
2、list
该标准容器是一个定义在 namespace std 中的模板,该模板的原型声明在头文件 <list> 中。list 是一个对容器元素的插入和删除操作进行了优化的序列。但与 vector 和 deque 相比,对元素的下标访问操作的低效是不能容忍的,因此 list 不提供这类操作,即不提供随机访问循环子,而提供双向循环子。这意味着 list 是典型的通过使用双链表实现的序列结构。
说明:双向链表,在任何位置增删元素都能在常数时间完成。不支持随机存取。
对于 list,front 操作和 back 操作都同样高效和方便。因此,如果希望使用 list 编写的代码演变为能应用于多种其他容器的通用代码,则使用更具广泛适用性的 back 操作是最好的选择。list 元素的插入和删除操作尤为高效,所以 list 更适合在插入和删除操作频繁的应用中使用。
#include "list"
#include "iostream"
using namespace std;
typedef list<int> LISTINT;
int main()
{
int rgTest1[] = {5,6,7};
int rgTest2[] = {10,11,12};
LISTINT listInt;
LISTINT::iterator i;
// Insert one at a time
listInt.insert (listInt.begin(), 2);
listInt.insert (listInt.begin(), 1);
listInt.insert (listInt.end(), 3);
// output: 1 2 3
cout << "listInt:";
for(i=listInt.begin();i!=listInt.end();i++)
cout << " " << *i;
cout <<endl;
// Insert 3 fours
listInt.insert(listInt.end(),3,4);
// output: 1 2 3 4 4 4
cout <<"listInt:";
for (i=listInt.begin();i!=listInt.end();++i)
cout <<" "<< *i;
cout<<endl;
// Insert an array at the end
listInt.insert(listInt.end(),rgTest1,rgTest1+3);
// output: 1 2 3 4 4 4 5 6 7
cout << "listInt:";
for (i=listInt.begin(); i!=listInt.end();++i)
cout << " " << *i;
cout <<endl;
// Insert another LISTINT
LISTINT listAnother;
listAnother.insert (listAnother.begin(),rgTest2,rgTest2+3);
listInt.insert (listInt.end(), listAnother.begin(), listAnother.end());
// output: 1 2 3 4 4 4 5 6 7 10 11 12
cout << "listInt:";
for (i=listInt.begin();i!=listInt.end();++i)
cout <<" "<<*i;
cout <<endl;
return 1;
}
3、deque
该标准容器是一个定义在 namespace std 中的模板,该模板的原型声明在头文件 <deque> 中。deque 是一个双向队列,也是一个优化序列。在 deque 两端的操作与 list 一样高效,对元素的下标操作的效率又与 vector 类似,而对容器元素的插入和删除操作的效率则介于 list 和 vector 之间。
说明:也是个动态数组,随机存取任何元素都能在常数时间完成(但性能次于vector)。在两端增删元素具有较佳的性能。
所有适用于vector的操作都适用于deque。deque还有push_front(将元素插入到前面)和pop_front(删除最前面的元素)操作
上述三种容器称为顺序容器,是因为元素的插入位置同元素的值无关。
B、关联式容器
关联式容器内的元素是排序的,插入任何元素,都按相应的排序准则来确定其位置。关联式容器的特点是在查找时具有非常好的性能。
set 即集合,set中不允许相同元素,multiset中允许存在相同的元素。
map与set的不同在于map中存放的是成对的key/value,并根据key对元素进行排序,可快速地根据key来检索元素;map同multimap的不同在于是否允许多个元素有相同的key值。
上述4种容器通常以平衡二叉树方式实现,插入和检索的时间都是 O(logN)。
内部元素有序排列,新元素插入的位置取决于它的值,查找速度快。
map关联数组:元素通过键来存储和读取;
set大小可变的集合,支持通过键实现的快速读取。
multimap支持同一个键多次出现的map类型;
multiset支持同一个键多次出现的set类型。
与顺序容器的本质区别
关联容器是通过键(key)存储和读取元素的,它要求定义一个比较操作进行元素操作。而顺序容器则通过元素在容器中的位置顺序存储和访问元素。
4、map该标准关联容器是一个定义在 namespace std 中的模板,该模板的原型声明在头文件 <map> 中。 map 是一个元素对(关键字,映射值)序列(注:Hash table (key, value pairs)),它提供了以关键字为基础的快速检索。map 中的每一个关键字必须是唯一的。map 提供双向循环子。
元素按照关键字升序排列,缺省情况下用 less 定义“小于”。
可以用pairs[key] 访形式问map中的元素。pairs 为map容器名,key为关键字的值。该表达式返回的是对关键值为key的元素的值的引用。(我们可以理解为map中存储的数据类型是pairs型)
如果没有关键字为key的元素,则会往pairs里插入一个关键字为key的元素,并返回其值的引用如:
map<int,double> pairs;
则 pairs[50] = 5; 会修改pairs中关键字为50的元素,使其值变成5。
例一:
#include <iostream>
#include <map>
using namespace std;
ostream & operator <<( ostream & o,const pair< int,double> & p)
{
o << "(" << p.first << "," << p.second << ")";
return o;
}
int main() {
typedef map<int,double,less<int> > mmid;
mmid pairs;
cout << "1) " << pairs.count(15) << endl;
pairs.insert(mmid::value_type(15,2.7));
pairs.insert(make_pair(15,99.3));//make_pair生成pair对象
cout << "2) " << pairs.count(15) << endl;
pairs.insert(mmid::value_type(20,9.3));
mmid::iterator i;
cout << "3) ";
for( i = pairs.begin(); i != pairs.end();i ++ )
cout << * i << ",";
cout << endl;
cout << "4) ";
int n = pairs[40];//如果没有关键字为40的元素,则插入一个
for( i = pairs.begin(); i != pairs.end();i ++ )
cout << * i << ",";
cout << endl;
cout << "5) ";
pairs[15] = 6.28; //把关键字为15的元素值改成6.28
for( i = pairs.begin(); i != pairs.end();i ++ )
cout << * i << ",";
return 0;
}
例二:
#include <iostream>
#include "numeric"
#include "string"
#include "map"
using namespace std;
typedef map<int,string,less<int> > INT2STRING;
int main()
{
INT2STRING theMap;
INT2STRING::iterator theIterator;
string theString="";
int index;
theMap.insert(INT2STRING::value_type(0,"Zero"));
theMap.insert(INT2STRING::value_type(1,"One"));
theMap.insert(INT2STRING::value_type(2,"Two"));
theMap.insert(INT2STRING::value_type(3,"There"));
theMap.insert(INT2STRING::value_type(4,"Four"));
theMap.insert(INT2STRING::value_type(5,"Five"));
theMap.insert(INT2STRING::value_type(6,"Six"));
theMap.insert(INT2STRING::value_type(7,"Seven"));
theMap.insert(INT2STRING::value_type(8,"Eight"));
theMap.insert(INT2STRING::value_type(9,"Nine"));
for(;;)
{
cout<<"ENter \"q\" to quit,or enter a number:\n";
cin>>theString;
if(theString=="q")
break;
for(index=0;index<theString.length();index++){
theIterator=theMap.find(theString[index]-'0');
if(theIterator!=theMap.end())
cout<<(*theIterator).second<<" ";
else
cout<<"[err]";
}
cout<<endl;
}
return 1;
}
hopegrace 发布了177 篇原创文章 · 获赞 24 · 访问量 1万+ 私信 关注
标签:insert,pairs,listInt,cout,STL,简介,元素,begin,模板 来源: https://blog.csdn.net/hopegrace/article/details/104154468