1. 首页>>POS机问答>>行业资讯

C++ stl容器详解_Eliauk

​ C++中为使用者提供了标准模板库 (Standard Template Library,STL),其中封装了很多相当实用的容器(可以先把容器理解成能够实现很多功能的东西),不需要费力去实现它们的细节而直接调用函数来实现很多功能,十分方便。下面介绍几个常用的容器,读者应当动手实现其中的例子,这对掌握它们的用法大有帮助(其中 queue、priority_queue、stack 可以等阅读到下一章节关于队列和栈的内容时再看)。

24银联POS机,拉卡拉电签4g产品办理

​ vector翻译为向量,但是这里使用“变长数组”的叫法更容易理解,也即“长度根据需要而自动改变的数组”。在考试题中,有时会碰到只用普通数组会超内存的情况,这种情况使用vector会让问题的解决便捷许多。另外,vector 还可以用来以邻接表的方式储存图,这对无法使用邻接矩阵的题目(结点数太多)、又害怕使用指针实现邻接表的读者是非常友好的,写法也非常简洁。

如果要使用vector,则需要添加vector 头文件,即#include 。除此之外,还需要在头文件下面加上一句“using namespace std;",这样就可以在代码中使用vector了。下面来看vector的一些常用用法。

​ 上面这个定义其实相当于是一维数组name[SIZE],只不过,其长度可以根据需要进行变化,比较节省空间,说通俗了就是“变长数组”。

17拉卡拉电签2g产品办理实图

​ 和一维数组一样,这里的 typename 可以是任何基本类型,例如 int、double、char、结构体等,也可以是STL标准容器,例如vector、set、queue等。需要注意的是,如果typename也是一个STL容器,定义的时候要记得在 >> 符号之间加上空格,因为一些使用C++11之前标准的编译器会把它视为移位操作,导致编译错误。下面是一些简单的例子.

​ 可以很容易联想到二维数组的定义,即其中一维是一个数组的数组。那么vector数组也是一样,即 Arrayname[] 中的每一个元素都是一个vector。初学者可以把vector数组当作两个维都可变长的二维数组理解。

然后来看定义vector数组的方法:

1银联刷卡机,拉卡拉pos机智能刷卡机

这样 Arrayname[0]-Arrayname[arraySize -1]中每一个都是一个vector 容器。

与vector name不同的是,这种写法的一维长度已经固定为 arraySize,另一维才是“变长”的(注意体会这两种写法的区别)。

vector一般有两种访问方式:通过下标访问或通过迭代器访问。下面分别讨论这两种访问方式。

2拉卡拉电签新品pos_4g

和访问普通的数组是一样,对一个定义为vector vi的vector容器来说,直接访问vi[index]即可(如vi[0]、vi[1])。当然,这里下标是从0到vi.size()-1,访问这个范围外的元素可能会运行出错。

迭代器(iterator)可以理解为一种类似指针的东西,其定义是:

这样it就是一个vector::iterator型的变量 (虽然这个类型看起来很长),其中typename 就是定义vector 时填写的类型。下面是typename为int和double的举例:

18拉卡拉电签2g产品办理实图

这样就得到了迭代器it,并且可以通过*it来访问vector里的元素。

例如,有这样定义的一个vector容器:

可以通过类似下标和指针访问数组的方式来访问容器内的元素:

41银联POS机,拉卡拉电签pos刷卡机,智能pos机

从这里可以看出vi[i]和*(vi.begin()+i)是等价的。

既然上面说到了 begin()函数的作用为取vi的首元素地址,那么这里还要提到end()函数。和 begin()不同的是,end()并不是取vi的尾元素地址,而是取尾元素地址的下一个地址。end()作为迭代器末尾标志,不储存任何元素。美国人思维比较习惯左闭右开,在这里begin()和end()也是如此。

除此之外,迭代器还实现了两种自加操作:++i和i++(自减操作同理),于是有了另一种遍历vector中元素的写法:

23拉卡拉电签2g产品办理

最后需要指出,在常用STL容器中,只有在vector和string中,才允许使用vi.begin()+3这种迭代器加上整数的写法。

有添加就会有删除,pop_back()用以删除vector的尾元素,时间复杂度为O(1)。

示例如下:

9银联刷卡机,拉卡拉pos机产品图

size()用来获得vector中元素的个数,时间复杂度为O(1)。size()返回的是unsigned类型,不过一般来说用%d不会出很大问题,这一点对所有STL容器都是一样的。

示例如下:

clear()用来清空vector中的所有元素,时间复杂度为 O(N),其中N为 vector中元素的个数。

6银联刷卡机,拉卡拉pos机,智能wifi扫码刷卡机

示例如下:

erase()有两种用法:删除单个元素、删除一个区间内的所有元素。时间复杂度均为O()。

• 删除单个元素。

10银联刷卡机,拉卡拉pos机产品演示

erase(it) 即删除迭代器为 it 处的元素。

示例如下:

• 删除一个区间内的所有元素。

39银联POS机,拉卡拉电签pos刷卡机4g2

erase(first,last)即删除[first, last)内的所有元素。

示例如下:

由上面的说法可以知道,如果要删除这个 vector内的所有元素,正确的写法应该是

7银联刷卡机,拉卡拉pos机4g电签无线刷卡机

vi.erase(vi.begin(), vi.end()),这正如前面说过,vi.end()就是尾元素地址的下一个地址。(当然更方便的清空vector的方法是使用vi.clear())。

• vector本身可以作为数组使用,而且在一些元素个数不确定的场合可以很好地节省空间。

• 有些场合需要根据一些条件把部分数据输出在同一行,数据中间用空格隔开。由于输出数据的个数是不确定的,为了更方便地处理最后一个满足条件的数据后面不输出额外的空格,可以先用vector记录所有需要输出的数据,然后一次性输出。

2银联刷卡机,拉卡拉pos机4g电签版

使用vector 实现邻接表可以让一些对指针不太熟悉的读者有一个比较方便的写法。

set翻译为集合,是一个内部自动有序且不含重复元素的容器。在考试中,有可能出现需要去掉重复元素的情况,而且有可能因这些元素比较大或者类型不是int型而不能直接开散列表,在这种情况下就可以用set来保留元素本身而不考虑它的个数。当然,上面说的情况也可以通过再开一个数组进行下标和元素的对应来解决,但是set提供了更为直观的接口,并且加入set之后可以实现自动排序,因此熟练使用set可以在做某些题时减少思维量。

如果要使用set,需要添加set头文件,即 #include 。除此之外,还需要在头文件下面加上一句:“using namespace std;”,这样就可以在代码中使用set了。

17拉卡拉电签2g产品办理实图

其定义的写法其实和vector基本是一样的,或者说其实大部分STL都是这样定义的。这里的typename依然可以是任何基本类型,例如int、double、char、结构体等,或者是STL标准容器,例如vector、set、queue等。

和前面vector中提到的一样,如果typename是一个STL容器,那么定义时要记得在>>符号之间加上空格,因为一些使用C++11之前标准的编译器会把它视为移位操作,导致编译错误。下面是一些简单的例子:

这样Arrayname[0]~Arrayname[arraySize-1]中的每一个都是一个set容器。

24银联刷卡机,拉卡拉pos机,智能pos机

typename就是定义set时填写的类型,下面是typename为int和char的举例:

这样就得到了迭代器it,并且可以通过*it来访问set里的元素。

由于*除开vector和string之外的STL容器都不支持 (it + i)的访问方式,因此只能按如下方式枚举:

26银联POS机,拉卡拉电签4g产品办理

insert(x)可将x插入set容器中,并自动递增排序和去重,时间复杂度O(logN),其中N为set内的元素个数,示例参见“set容器内元素的访问”。

find(value)返回set中对应值为value的迭代器,时间复杂度为O(logN),N为set内的元素个数。

• st.erase(it),it为所需要删除元素的迭代器。时间复杂度为O(1)。可以结合find()函数来使用。示例如下:

18银联刷卡机,拉卡拉pos机4g

• st.erase(value),value为所需要删除元素的值。时间复杂度为O(logN),N为set内的元素个数。示例如下:

st.erase(first,last)可以删除一个区间内的所有元素,其中first为所需要删除区间的起始迭代器,而last则为所需要删除区间的末尾迭代器的下一个地址,也即为删除(first,last)。时间复杂度为O(last - first)。示例如下:

clear()用来清空set中的所有元素,复杂度为O(N),其中N为set内元素的个数。

43银联POS机,拉卡拉电签pos刷卡机2g版本

示例如下:

set最主要的作用是自动去重并按升序排序,因此碰到需要去重但是却不方便直接开数组的情况,可以尝试用set解决。

延伸:set中元素是唯一的,如果需要处理不唯一的情况,则需要使用multiset。另外, C++11标准中还增加了unordered set,以散列代替set内部的红黑树(Red Black Tree,一种自平衡二叉查找树)实现,使其可以用来处理只去重但不排序的需求,速度比set要快得多,有兴趣的读者可以自行了解,此处不多作说明。

8拉卡拉电签POS刷卡机4g版

在C语言中,一般使用字符数组char str[]来存放字符串,但是使用字符数组有时会显得操作麻烦,而且容易因经验不足而产生一些错误。为了使编程者可以更方便地对字符串进行操作,C++在STL中加入了string类型,对字符串常用的需求功能进行了封装,使得操作起来更方便,且不易出错。

如果要使用string,需要添加string头文件,即#include (注意string.h和string是不一样的头文件)。除此之外,还需要在头文件下面加上一句:“using namespace std;”,这样就可以在代码中使用string了。下面来看string的一些常用用法。

定义string的方式跟基本数据类型相同,只需要在string后跟上变量名即可:

24银联刷卡机,拉卡拉pos机,智能pos机

如果要读入和输出整个字符串,则只能用cin和cout:

上面的代码对任意的字符串输入,都会输出同样的字符串。

那么,真的没有办法用printf来输出string吗?其实是有的,即用c_str()将string类型转换为字符数组进行输出,示例如下:

1银联刷卡机,拉卡拉pos机智能刷卡机

一般仅通过(1)即可满足访问的要求,但是有些函数比如insert()与erase()则要求以迭代器为参数,因此还是需要学习一下string迭代器的用法。

由于string不像其他STL容器那样需要参数,因此可以直接如下定义:

这样就得到了迭代器it,并且可以通过*it来访问string里的每一位:

9银联刷卡机,拉卡拉pos机产品图

最后指出,string和vector一样,支持直接对迭代器进行加减某个数字,如str.begin()+3的写法是可行的。

事实上,string的函数有很多,但是有些函数并不常用,因此下面就几个常用的函数举例。

这是string的加法,可以将两个string直接拼接起来。

1拉卡拉智能pos_wifi_4g

示例如下:

length()返回string的长度,即存放的字符数,时间复杂度为O(1)。size()与length()基本相同。

示例如下:

29银联POS机,拉卡拉电签4g,收款宝盒

string的insert()函数有很多种写法,这里给出几个常用的写法,时间复杂度为O(N)。

①insert(pos,string),在pos号位置插入字符串string。

示例如下:

24银联POS机,拉卡拉电签4g产品办理

②inserte(it,it2,t3),it为原字符串的欲插入位置,it2和it3为待插字符串的首尾迭代器,用来表示串[t2,it3)将被插在it的位置上。

示例如下:

erase()有两种用法:删除单个元素、删除一个区间内的所有元素。时间复杂度均为O)。

21银联刷卡机,拉卡拉pos机4g,wifi智能刷卡机

①删除单个元素。

str.erase(it)用于删除单个元素,it为需要删除的元素的迭代器。

示例如下:

6银联刷卡机,拉卡拉pos机,智能wifi扫码刷卡机

• str.erase(first,last),其中first为需要删除的区间的起始迭代器,而last则为需要删除的区间的末尾迭代器的下一个地址,也即为删除[frst,last)

示例如下:

• str.erase(pos,length),其中pos为需要开始删除的起始位置,length为删除的字符个数。

14拉卡拉电签2g产品办理实图

示例如下:

substr(pos,len)返回从pos号位开始、长度为len的子串,时间复杂度为O(Ien)。

示例如下:

18银联刷卡机,拉卡拉pos机4g

string::npos 是一个常数,其本身的值为-1,但由于是unsigned_int类型,因此实际上也可以认为是unsigned_int类型的最大值。string::npos用以作为find函数失配时的返回值。例如在下面的实例中可以认为string::npos等于-1或者4294967295。

示例如下:

str.find(str2),当str2是sr的子串时,返回其在str中第一次出现的位置;如果str2不是str的子串,那么返回string::npos。

17拉卡拉电签2g产品办理实图

str.find(str2,pos),从str的pos号位开始匹配str2,返回值与上相同。

时间复杂度为O(nm),其中n和m分别为str和str2的长度。

示例如下:

25银联POS机,拉卡拉电签4g产品演示

str.replace(pos,len,str2)把str从pos号位开始、长度为len的子串替换为str2。

str.replace(it1,it2,str2)把str的迭代器[it1,it2)范围的子串替换为str2。

时间复杂度为O(str.length()).

37银联POS机,拉卡拉电签pos刷卡机刷卡演示

示例如下:

本文采摘于网络,不代表本站立场,转载联系作者并注明出处:http://xwsfz.com/xmt/4177.html

联系我们

在线咨询:点击这里给我发消息

微信号:+(86) 135 5181 5878

工作日:8:30-20:30
节假日:9:30-18:30

微信联系