c++ primer 整理(七)容器

第六部分是io,比较少,下次有时间看了再整理一下。

其实这部分学起来挺无聊的,不过却是很有用,介绍了大量的函数、操作(加上后边的泛型算法),对于使用容器开发程序是很有帮助的。

啥也不说了,开始吧。

顺序容器有6个:主要说明他们的访问、插入删除特性。

vector。vector都知道,可变长数组;可以快速随机访问,(就是像数组那样访问任意一个元素),尾后插入删除速度很快,其他位置比较慢。

deque,deque就是队列,不过这个是双向的队列,啥意思?就是头部/尾部都可以插入,删除,速度很快。也支持随机访问。

list。就是链表。就是那个当年学二叉树什么的用的那个,不过这个也是双向的,只能双向顺序访问,就是i++,--i这样的。不过在任意一个位置插入、删除的速度都很快。(链表嘛,当然了)

forward_list。真·链表。只能单向(前向)顺序访问,可以任意位置插入,删除。

array。容器形式的数组,和数组的性质一样。

string。类似vector,不过只放字符。可以快速随机访问,尾部插、删速度快。

string和vector是存在连续的内存空间中的,所以插入删除速度不快。

然后就是,容器的操作了。

基本操作:

类型别名:iterator--迭代器,const_iterator--常量迭代器,不可修改元素;size_type--无符号整型;difference_type带符号整形,迭代器的距离类型;reference/const_reference--元素左值类型。使用他们的时候必须显式使用其类名,如:list::iterator iter;

构造函数初始化:C c1--默认构造函数,若为array则按照元素的默认方式初始化,其他为空;C c1(c2)--用c2的拷贝构造c1,array必须保证两者大小一致;C c(b,e)--将迭代器b至e的元素拷贝至c(array不支持);C c{a,b,c...}/c={a,b,c...}列表初始化,对于array元素数必须<=容器大小。只有顺序容器(无array)才能接受大小参数:C seq(n)(string不适用),C seq(n,t)。

而使用拷贝初始化时,必须保证容器类型一致(Tt和T都要一样),用范围拷贝初始化时要保证类型可转换,

如:vectora={"a","an","the"};vector b(a);//错。vector c(a.begin(),a.end());//正确。

对于array:array;必须规定元素类型和大小。内置数组不能拷贝或赋值,但是array可以只要大小、类型一致。但是array不能用{}赋值(可以初始化)。

赋值:c1=c2;   c1={a,b,c...};(此不适合array)

assign赋值(顺序容器,除array):seq.assign(b,e)--使用迭代器b和e的范围进行赋值,seq.assign(il)--使用列表il替换元素,seq.assign(n,t)--n个t替换seq中元素。

交换:a.swap(b);swap(a,b);交换类型相同的a和b的元素内容,大小不限。但是只是交换容器的数据结构,所以迭代器,引用和指针都不会失效。但array的swap是元素交换。string使用会导致迭代器,引用和指针失效。

大小:c.size()(forward_list不支持)   c.max_size()--c中最大元素的数目;c.empty()若c为空则返回false。

添加删除元素:c.insert(args)--args拷贝入c;c.emplace(inits)--用inits构造c中一个元素;c.erase(args)--删除args指定的元素;c.clear()删除c中所有

关系运算符:==,!=所有容器支持;<,<=,>,>=只有顺序容器支持。比较大小的规则:大小相等,元素对应--相等;大小不等,a是b的子集--a

迭代器支持的操作:*iter,iter->mem,++iter,--iter,iter1==iter2,iter1!=iter2。但是forward_list不支持--。对于list形的迭代器,不支持>,<,因为他们不是安内存顺序排放的,指针大小与元素的顺序没有关系。

迭代器的范围:[b,e)。一些小规律:begin==end,范围为空;begin!=end,总有至少一个元素,begin指向范围的第一个元素。

begin和end:指向首元素和尾后元素的迭代器。cbegin和cend则是返回const的,可以以用法决定使用哪种,如不需要写时,就用c的版本;也可以直接使用auto生成,只取决于对象是不是const:如,auto iter=a.begin();。

添加元素:c.push_back(t),c.emplace_back(t).尾部创建,返回void,emplace系列是构造元素将参数传递给元素类型的构造函数。如有类sales_data c,可以c.emplace_back("2222",25,16);但是不能c.push_back("2222",25,16);,因为push没有接受3个参数的,我们只能c.push_back(sales_data("2222",25,16));,emplace_back返回void。

c.push_front()和c.emplace_front()(返回void),c.insert()和c.emplace()同理。c.insert(p,t)--p之前插入t,c.emplace(p,args)--p之前添加args(返回新添加元素的迭代器),c.insert(p,n,t)--p之前插入n个t,c.insert(p,b,e)--p之前插入b和e的元素,c.insert(p,il)--p之前插入列表il中的元素,返回p。这里的p,b,e都是迭代器。

顺序容器访问元素:c.back()返回尾元素的引用,c.front()首元素的引用,c[n],c.at(n)同c[n],但是若越界则抛出out_of_range异常。

删除元素:c.pop_back()(不支持forward_list),c.pop_front()(不支持vector和string),删除尾/首元素,返回void;c.erase(p),c.erase(b,e)返回最后一个被删元素之后的迭代器,p是尾后迭代器则未定义,若e为尾后迭代器则返回尾后迭代器。c.clear()全部清除。

forward_list的删除/插入元素:

lst.before_begin()返回首前迭代器;lst.insert_after(),操作和insert一样,但是是在p之后,p为尾后迭代器则未定义;lst.erase_after(),删除p之后/b之后的位置,返回同erase。

改变容器大小:resize()。改变是从尾部开始的。

tip,不要保存end返回的迭代器,因为插入/删除vector,string或者在deque除首尾外的位置插入/删除元素都会使end失效。

vector内存的变化:当被初始化或者赋值后会预分配空间,当添加/插入操作使空间沾满后会再次分配一部分空间,大致是之前的一倍(靠具体实现)。

string的其他操作

构造:sting s(cp,n)--cp指向的数组的前n个字符的拷贝(数组数>=n);string s(s2,pos2)--s从s2的pos2开始拷贝;string s(s2,pos2,len2)--s从s2的pos2开始拷贝len2个,但是至多从pos2拷贝至end。若开始位置超范围,则抛出out_of_range。可使用成员函数.shrink_to_fit()将多余内存退回系统。

用substr(pos,n):s2=s.substr(b,e);b默认为0,e可没有(默认为end)。

string的操作大全:s.insert(pos,args);pos可以是下标(返回指向s的引用)或迭代器(返回指向第一个插入字符的迭代器)。

s.erase(pos,len);pos必须是下标(返回指向s的引用)。

s.assign(args);把s替换为args,返回指向s的引用。

s.append(args);args添加到s尾,(返回指向s的引用)。

s.replace(range,args);把range中的替换为args。range:一对迭代器或一个下标和一个长度。(返回指向s的引用)

args可以是str;str,pos,len;cp,len;cp;n,c(n个字符c);b,e。append和assign可以使用所有形式,replace和insert要结合range,见书324页(实在懒得写)。

搜索:s.find(args)--查找args第一次出现的位置。

s,rfind(args)--查找最后一次出现的位置。

s.find_first_of(args)--查找args中任意一个字符第一次出现的位置。很有趣的查找,如string s={"abc1"};s.fin_first_of("0123456789");就会返回3(下标)。

s.find_last_of(args)--查找args中任意一个字符最后一次出现的位置。

s.find_first_not_of(args)--查找args中第一个不在args中的字符。

s.find_last_not_of(args)--查找args中最后一个不在args中的字符。

args的形式:c,pos;s2,pos;cp,pos;cp,pos,n。前3个pos默认为0,最后一个没有默认值。

比较:compare:s.compare(args)。args:s2;pos1,n1,n2;pos1,n1,s2,pos2,n2;cp(cp指向的以空字符结尾的字符数组);pos1,n1,cp;pos1,n1,cp,n2。

数值转换:

c++11数值现在可以和string转换:

to_string(val)--将任意数转换为字符串,小整形会被提升。

stoi(s,p,b)

stol(s,p,b)

stoul(s,p,b)

stoll(s,p,b)--返回s的起始子串的数值,返回类型由函数决定;b为数制,默认为10(10进制);p是size_t指针,保存s中第一个非数值字符的下标,默认为0。

stof(s,p)

stod(s,p)

stold(s,p)

基本上这一部分结束了,感觉这样写好累,下一章写泛型算法的时候换个方法,直接总结出现的algorithm和泛型的使用好了~~

你可能感兴趣的:(c++,primer学习整理)