学习C++——顺序容器(1)

1、顺序容器概述

以下表格列出了标准库中的顺序容器,所有的顺序容器都提供了快速顺序访问元素的能力。
顺序容器类型
vector可变大小数组。支持快速随机访问。元素是连续存储。
deque双端队列。支持快速随机访问。在头尾位置插入、删除速度很快。
list双向链表。支持双向顺序访问。在任何位置插入、删除速度都很快。
forward_list单向链表。只支持单向顺序访问。在任何位置插入、删除速度都很快。
array固定大小数组。支持快速随机访问。不能添加或删除元素。
string与vector类似的容器,但专门用于保护字符。随机访问快,在尾部插入或删除速度快。

forward_list和array是新的C++标准增加的类型。

确定使用哪种顺序容器

通常,使用vector是最好的选择,除非有很好的理由选择其他容器。

以下是一些选择容器的原则:
  • 除非你有很好的理由选择其他容器,否则应使用vector
  • 如果你的程序有很多小的元素,且额外开销很重要,则不要使用list和forward_list
  • 如果程序要求随机访问元素,应使用vector或deque
  • 如果要求在容器的中间插入或删除元素,应使用list或forward_list
  • 如果需要在头尾位置插入或删除元素,但不会在中间位置进行插入或删除操作,则使用deque

2、容器库概述

每个容器都定义在一个头文件中,文件名和类型名相同。即,deque定义在头文件deque中,list定义在头文件list中,等等。

顺序容器几乎可以保存任意类型的元素。特殊情况下是,定义一个容器,其元素类型是另外一个容器。如:vector<vector<string>>  lines;

容器操作:

类型别名 
iterator此容器类型的迭代器类型
const_iterator可以读取元素,但是不能修改元素的迭代器类型
size_type无符号整数类型,保存此种容器类型最大可能容器的大小
difference_type带符号整数类型,足够保存两个迭代器之间的距离
value_type元素类型
reference元素的左值类型,与value_type & 含义相同
const_reference元素的const左值类型(即,cosnt value_type &)

迭代器运算

vector、string、deque和array迭代器支持的运算
iter+n迭代器指向的位置向前移动n个位置
iter-n迭代器指向的位置向后移动n个位置
iter += niter = iter + n
iter  -= niter = iter - n
iter1- iter2 
>,>=,<,<=iter1如果在iter2指向的位置之前,则iter1小于iter2

迭代器范围

[ bigen, end)
	while(begin != end)
	{
		*begin = val;//将begin指向位置的元素值设为val
		++begin;//移动迭代器,获取下一个位置
	}

迭代器的类型

  • auto len = line.size();//len的类型是string::size_type;
  • vector<int>::iterator  it;//it能读写vector<int>的元素。
  • vector<int>::const_iterator  it2;//it2只能读元素,不能写元素。
  • 方向容器的成员,reverse_iterator和const_reverse_iterator,它们和之前的那两个的++,--含义是相反的,其它含义都是一样的。

begin和end成员

	list<string>a = {"ya","xi","ku"};
	auto it1 = a.begin();//list<string>::iterator
	auto it2 = a.rbegin();//list<string>::reverse_iterator
	auto it3 = a.cbegin();//list<string>::const_iterator
	auto it4 = a.crbegin();//list<string>::const_reverse_iterator

与顺序容器大小相关的构造函数

        vector<int> ivec(10, -1);//10个int元素,每个值都初始化为1
	list<string> svec(10, "hello");//10个string元素,每个值初始化为hello
	forward_list<int> ivec(10);//10个int元素,每个都初始化为0
	deque<string> svec(10);//10个string元素,每个都是空字符串

列表初始化(C++11标准)

	list<string> peo = {"ya", "xi", "kui"};
	vector<char *> peo = {"ya", "xi", "kui"};

标准库array具有固定的大小

与内置数组一样,标准库array的大小也是类型的一部分。当定义一个array时,除了指定元素类型,还要指定容器大小。

	array<int, 42>       //这是一个数据类型,保存42个int的数组
	array<string, 10>    //这是一个数据类型,保存10个string的数组
	array<int, 10> ival1;//10个默认初始化的int
	array<int, 10> ival2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};//列表初始化
	array<int, 10> ival3 = {42};//ival[0] = 42,其余元素都是0

赋值和swap

容器赋值运算
c1 = c2将c1中的元素变为c2中元素的拷贝。c1,c2必须有相同的类型
c = {a,b,c....}将c中的元素变为初始化列表中元素的拷贝,array除外。
swap(c1, c2)交换c1和c2的元素。两个具有相同的类型。速度比从c2向c1拷贝元素快得多。
c1.swap(c2)交换c1和c2的元素。两个具有相同的类型。速度比从c2向c1拷贝元素快得多。等价于swap(c1, c2)
  
seq.assign(b,e)将seq中的元素替换为迭代器b和e所表示的范围中的元素。迭代器b和e不能指向seq中的元素。
seq.assign(i1)将seq中的元素替换为初始化列表i1中的元素
seq.assign(n, t)将seq中的元素替换为n个值为t的元素

备注:

  • assign操作不适用于关联容器和array
  • 赋值相关运算会导致指向左边容器内部的迭代器,引用和指针失效。
  • swap操作将容器内容交换不会导致指向容器的迭代器,引用和指针失效。(容器类型为array和string的情况除外)

使用assign

赋值运算符要求左边和右边的运算对象具有相同的类型。但是assign允许我们从一个不同但是相容的类型赋值,或者从一个容器的一个子序列赋值。
	list<string>  names;
	vector<const char *> oldstyle;
	names = oldstyle;//错误,容器类型不匹配
	names.assign(oldstyle.cbegin(), oldstyle.cend());
	//对assign的调用将names中的元素替换为迭代器指定的范围中的元素的拷贝。
第二个版本的assign,接受一个整型值和一个元素值
<span style="white-space:pre">	</span>list<string> slist(1);//1个元素,为空string
	slist.assign(10, "Hiya");//10个元素,每个都是“Hiya”

使用swap

	vector<string>  svec1(10);
	vector<string>  svec2(24);
	swap(svec1,svec2);
	//调用swap后,svec1将包含24个string元素,svec2将包含10个string元素。

  • 除了string之外,指向容器的迭代器,引用和指针在swap之后都不会失效。它们仍然指向swap之前所指向的那些元素。但是这些元素已经属于是不同的容器了。
  • swap两个array会真正交换它们的元素。在swap操作之后,指针、引用和迭代器所绑定的元素保持不变,但元素值已经与另一个array中对应元素的值进行了交换。

容器大小操作

  • 成员函数size返回容器中元素的数目
  • empty当size为0时返回布尔值true,否则返回false。
  • max_size返回一个大于或等于该类型容器所能容纳的最大元素数的值。
  • forward_list支持max_size和empty,但是不支持size。

关系运算符

==, !=,  >, >=, <, <=
关系运算符左右两边的运算对象必须是相同类型的容器,且必须保存相同类型的元素。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值