容器 泛型算法

来源:互联网 发布:tensorflow显卡要求 编辑:程序博客网 时间:2024/05/19 18:45

容器介绍

1.标准库定义了三种顺序容器类型:vector,list和deque(双端队列),同时还定义了三种顺序容器适配器:queue,priority_queue和stack
适配器是根据原始的容器类型所提供的操作,通过定义新的操作接口,来适应基础的容器类型
所有的容器都是类模板
2.一些容器特点
vector:存储连续,支持快速随机访问
list:支持快速插入/删除,存储不连续
deque:双端队列

stack:后进先出的栈(LIFO)
queue:先进先出队列(FIFO)
priority_queue:有优先级管理的队列



顺序容器

1.容器的初始化
C<T> c;
C<T> c(c2);
C<T> c(b,e);(使用迭代器初始化一段元素的副本,不要求容器类型相同,只要他们互相兼容,能够够将要复制的元素转换为所构建的新容器的元素类型,即可实现复制,因为指针就是迭代器,因此允许通过使用内置数据中的一对指针初始化容器)
例如 
char *words[] = {"stately","plump","buck","mulligan"};
size_t words_size = sizeof(words)/sizeof(char *);
list<string words2(words,words + words_size);
C<T> c(n,t);
C<T> c(n);
2.迭代器为所有标准库容器类型提供的运算
*iter
iter->mem
++iter
iter++
--iter
iter--
iter1 == iter2
iter1 != iter2
iter + n
iter - n
iter1 += iter2
iter1 -=iter2
iter1 - iter2(只有vector和deque容器支持此操作)
>,>=.<,<=(注意只有vector和deque支持此操作,list只能支持==,!=操作,因为它不是连续存储的)
迭代器失效的问题:当迭代器所指向的数被erase后,则会是的迭代器失效,使用无效迭代器将会导致严重的运行时错误。
3.容器定义的类型别名
size_type
iterator
const_iterator
reverse_iterator
const_reverse_iterator
difference_type存储两个迭代器差值的有符号整数
value_type元素类型
reference元素的左值类型,是value_type&的同义词
const_reference元素的常量左值类型,等效于const value_type&

c.begin()
c,end()
c.rbegin()
c.rend()
此四个操作的返回值取决于容器是否为const,如果不是,则返回iterator或reverse_iterator,如果是则返回const_iterator或者const_reverse_iterator

c.push_back(t)
c.push_front(t)(只使用与list和deque)
c.insert(p,t)在迭代器p所指向的元素前面插入值为t的新元素,返回新添加元素的迭代器
c.insert(p,n,t)在迭代器p所指向的元素前面插入n个值为t的新元素,返回void类型
c.insert(p,b,e)在迭代器p所指向的元素前面插入由迭代器b和e标记的返回内的元素,返回void类型
(insert可能会导致整个容器的重新加载,这样的话,该容器设计的所有迭代器都会失效)

容器的比较跟字符串比较类型,必须保证容器类型和元素类型相同例如 vector<int>不能与vector<float>比较

c.size()
c.max_size()
c.empty()
c.resize(n)调整容器的大小为n
c.resize(n,t)调整容器的大小为n,所有新添加的元素值都为t

c.back()返回容器c的最后一个元素的引用,如果c为空,则该操作未定义
c.front()返回容器c的第一个元素的引用,如果c为空,则改操作未定义
c[n]返回下表为n的元素的引用,如果n<0或n>=n.size(),则该操作未定义(只适用于vector和deque)
c.at(n)返回下标为n的元素的引用。如果下表越界,则该操作未定义(只适用于vector和deque容器)

c.erase(p)删除迭代器p所指向的元素,返回一个迭代器,它指向被删除元素后面的元素
c.erase(b,e)删除迭代器b和e所标记的范围内所有的元素,返回一个迭代器,它指向被删除元素段后面的元素
c.clear()删除容器c内的所有元素,返回void
c.pop_back()删除容器c的最后一个元素,返回void
c.pop_front()删除容器c的第一个元素,返回void(只适用于list或deque容器)


c1 = c2容器的赋值操作首先删除其左操作数容器中的所有元素,然后将右操作数容器的所有元素插入到左边容器中
c1.swap(c2)
c.assign(b,e)
c.assgin(n,t)将容器c重新设置为存储n个值为t的元素,操作首先是删除容器中所有元素,然后将其参数所指定的新元素插入到该容器中
带有与对迭代器参数的assign操作允许我们将一个容器的元素赋给另一个不同类型的容器

c.capacity()获取容器需要分配更多的存储空间之前能够存储的元素总数
c.reverse()告诉容器应该预留多少个元素的存储空间,当超过时,会按照一定策略增加容量
c.resize()是设置c中存放值的大小,相当于增加和减少值,这样可能会影响c.reserve


String
1.string不能使用front,back和pop_back操作
2.只使用与string的操作 substr,append和replace
3.string类型的查找操作
s.find(args)
s.rfind(args)
s.find_first_of(args)
s.find_last_of(args)
s.find_first_not_of(args)
s.find_last_not_of(args)
注意args参数样式
c,pos:从下标pos开始查找字符c
s2,pos:从下标pos开始查找string类型的s2
cp,pos:从下标pos开始,查找指针cp所指向的C风格的以空字符结束的字符串
cp,pos,n:从下标pos开始,查找指针cp所指向数组的前n个字符

容器适配器:queue,priority_queue和stack(适配器中的一种,还有迭代器适配器和函数适配器
1.容器适配器让一种已存在的容器类型采用另一种不同的抽象类型的工作方式实现
2.适配器的初始化
deque<int> deq;
stack<int> stk(deq);
3.默认的stack和queue都基于deque容器实现,而priority_queue则在vector容器上实现,如果stack要用vector赋值则必须显示声明例如:stack<string,vector<string> >
注意stack栈可以建立在vector,list或者deque容器之上,但是queue适配器要求其关联的基础容器必须提供push_front,因此不能建立在vector容器上
priority_queue适配器要求提供随机访问,因此可以建立在vector或deque容器上,但不能建立在list容器上
4.栈适配器操作
s.empty();
s.size();
s.pop();
s.top();
s.push(item);在站定压入新元素
5.队列和优先队列支持的操作
q.empty()
q.size()
q.pop()
q.front()返回队首元素的值,但不删除该元素,只使用于队列
q.back()返回队尾元素的值,但不删除该元素,只适用于队列
q.top()返回具有最高优先级的元素值,但不删除该元素,只使用与优先级队列
q.push(item)



关联容器
1.定义:关联容器通过键(key)存储和读取元素,关联容器类型如下:
map:关联数组,元素通过键来存储和读取,例如字典是map的一种很好的应用,单词是键,解释是值
set:大小可变的集合,支持通过键实现和快速读取,
multimap:支持同一个键多次出现的map类型,即允许多元素拥有相同的键
multiset:支持同一个键多次出现的set类型
2.标准库类型-pair类型该类型在utility头文件中定义
pair<T1,T2> p1;创建一个空的pair对象它的两个元素分别是T1和T2类型,采用值初始化
pair<T1,T2> p1(v1,v2)第一个初始化为v1,第二个初始化为v2
make_pair(v1,v2)以v1和v2值创建一个新的pair对象,其元素类型分别是v1和v2的类型
p1<p2遵循字典顺序
p1 == p2
p.first
p.second
3.map通过可理解为关联数组,可使用键作为下表来获取一个值
map构造函数
map<k,v> m;
map<k,v> m(m2);
map<k,v> m(b,e);
在使用关联容器时,它的键不但有一个类型,而且还有一个相关的比较函数,默认情况下,标准库使用键类型定义的<操作符来实现键的比较。键值必须支持<操作(list容器不支持)
map的value_type是pair类型,它的值成员可以修改,但键成员不能修改。

map添加元素
map<string,int> word_count;
word_count["Anna"] = 1;(此表达式做了4步:(1)在word_count中查找键为Anna的元素,没有找到(2)将一个新的键-值对插入到word_count中,键是const string,值为0(3)将这个新的键-值对插入到word_count中,(4)读取新插入的元素,并将它的值赋给为1)

map::insert使用
m.insert(e) e为在m上的value_type类型的值   word_count.insert(map<string,int>::value_type("Anna",1));创建一个pair对象,直接插入到map容器中,返回值包含一个迭代器和一个bool值的pair对象 例如 pair<map<string,int>::iterator,bool> ret = word_count.insert(make_pair(word,1));
value_type是pair<constK,V>类型的同义词
m.insert(beg,end)
m.insert(iter,e)

不修改map对象的查询操作(因为下标操作可能会添加元素)
m.count(k)返回m中k的出现次数
m.find(k)如果m中存在按k索引的元素,则返回该元素的迭代器,否则返回超出末端迭代器

从map对象中删除元素
m.erase(k)删除键为k的元素,返回size_type类型的值,表示删除的元素个数
m.erase(p)删除迭代器所指向的元素,p必须指向m中确实存在的元素
m.erase(b,e)删除迭代器b到e之间的元素 返回void类型

4.set只是单纯的键的集合,没有所关联的值,只需判断某值是否存在
set不支持下标操作符
set的value_type不是pair类型,而是与key_type相同的类型
5.set和map一个键只能对应一个实例,但是multiset和multimap一个键可以对应多个实例



泛型算法

1.标准库没有给容器添加大量的功能函数,而是选择提供一组算法,它不依赖特定的容器类型,是“泛型的”,可以作用在不同类型的容器和不同类型的元素中
2.泛型算法明确要求
(1)需要某种遍历集合的方式:能够从一个元素向前移到下一个元素(迭代器解决)
(2)必须能够知道是否到达了集合的末尾(用迭代器)
(3)必须能够对容器中的每一个元素与被查找的元素进行比较()
(4)需要一个类型来指出元素在容器中的位置,或者表示找不到该元素
3.使用泛型算法必须包含algorithm头文件,标准库还定义了一组泛化的算术算法,使用这些算法必须包含numeric头文件




迭代器 
1.除了标准库所定义的迭代器不依赖与特定的容器,C++还提供了另外三种迭代器,在头文件iterator中
插入迭代器:这类迭代器与容器绑定在一起,实现在容器中插入元素的功能。
iostream迭代器:这类迭代器与输入或输出流绑定在一起,用于迭代遍历所关联的IO流
反向迭代器:这些迭代器实现向后遍历,而不是向前遍历,所有容器都定义了自己的reverse_iterator类型,由rbegin和rend成员函数返回
2.插入迭代器:是一种迭代器适配器,C++提供了三种插入器
back_inserter:创建使用push_back实现插入的迭代器
front_inserter:使用push_front实现插入
inserter:使用insert实现插入
3.iostream迭代器 istream_iterator用于读取输入流,ostream——iterator用于写输出流
4.反向迭代器:一种反向遍历容器的迭代器,++运算符将访问前一个元素,而--运算则访问下一个元素
5.算法要求的迭代器操作分为五个类别
输入迭代器
输出迭代器
前向迭代器
双向迭代器
随机访问迭代器




0 0
原创粉丝点击