标准库类型vector(一)

标准库类型 vector 表示对象的集合,所有对象的类型都相同。每个对象都有一个对应的索引,用于访问对象。把 vector 称为容器,是因为它可以包含其他对象。

使用 vector,必须包含适当的头文件:

#include <vector>
using std :: vector;

vector 是一个类模板,通过提供一些额外信息来指定模板被实例化成什么样的类,信息的种类取决于模板。

实例化:编译器根据模板创建类或函数的过程,当使用模板时,需要指出编译器应把类或函数实例化何种类型。

方式:在模板名字后跟一对尖括号,在括号内放入信息
以 vector 为例:

vector<int> item;	//item 保存 int 类型的对象
vector<vector<string>> file;	//该向量的元素是 vector 对象

说明:
(1)早期声明语句处理元素为 vector 的 vector 对象:vector<vector< int> >
新式:vector<vector< int>>
(2)除不包含引用的 vector 外,其他大多数内置类型和类类型都可以构成 vector 对象。

一、定义和初始化 vector 对象

vector 模板控制着定义和初始化向量的方法。下表为初始化 vector 对象的方法:

vector< T > v1vector 保存类型为 T 对象,默认构造函数 v1 为空
vector< T > v2(v1)v2 是中包含有 v1 所有元素的副本
vector< T > v2 = v1与vector< T > v2(v1)等价
vector< T > v3(n, val)v3 包含 n 个值为 val 的元素
vector< T > v4(n)v4 包含了 n 个重复地执行了值初始化的对象
vector< T > v5{a,b,c…}v5 包含了初值个数的元素,每个元素被赋予相应的初始值
vector< T > v5={a,b,c…}等价于vector< T > v5{a,b,c…}

默认初始化 vector 对象:

vector<string> svec;	//默认初始化,svec不含任何元素

使用方式:先定义一个空 vector ,然后当运行时获取到元素的值后在逐一添加

1.列表初始化 vector 对象

c++11新标准提供:列表初始化(用花括号括起来的0个或多个初始元素值被赋给 vector 对象)

vector<string> articles = {“a”, “an”, “the”};

2.创建指定数量的元素

构造函数用元素个数来决定 vector 对象保存元素的个数,元素值指定每个元素的初始值:

vector<int> ivec(10,  -1); 	//10个 int 类型的元素,每个都被初始化为 -1
vector<string> svec(10, "hi!"); // 10个 string 类型的元素,每个都被初始化为 "hi!"

3.值初始化

如果没有指定元素的初始化时,标准库将自行提供一个元素初始值进行值初始化,并把它赋给容器中的所有元素。

vector<int> ivec(10);	//10个元素,每个都初始化为0
vector<string> sevc(10);	//10个元素,每个都是空 string 对象

两个特殊限制:
(1)有些类要求明确地提供初始值
(2)如果只提供了元素的数量而没有设定初始值,只能使用直接初始化:

vector<int> vi = 10;	//错误:必须使用直接初始化的形式指定向量大小

4.列表初始值还是元素数量

初始化的真正含义依赖于传递初始值时用的是花括号还是圆括号

vector<int> v1(10);        //v1 有10 个元素,每个元素的值都是0
vector<int> v2{10};      //v2 有1个元素,该元素的值是10

vector<int> v3(10, 1);   //v3 有10个元素,每个元素的值都是1
vector<int> v4{10, 1};  //v4 有2个元素,分别是10和1

使用圆括号:提供的值是用来构造vector对象的。

使用花括号:列表初始化该vector对象,也就是说,初始化过程尽可能地把花括号内的值当成是元素初始值的列表来处理,只有在无法执行列表初始化时才会考虑其他初始化方式

如果初始化时用了花括号的形式但是提供的值又不能用来列表初始化,就要考虑用这样的值来构造vector对象:

vector<string> v5{"hi"};	//列表初始化:v5 有一个元素
vector<string> v6 ("hi");          //错误,不能使用字符串字面值构建vector对象
vector<string> v7{10};            //v7有10个默认初始化的元素
vector<string> v8{10, "hi"};        //v8有10个值为“hi”的元素

列表初始化vector对象,花括号里的值必须与元素类型相同。确认无法执行列表初始化后,编译器会尝试用默认值初始化 vector 对象

二、向 vector 对象中添加元素

对 vector 对象来说,直接初始化的方式适用于三种情况:
1.初始值已知且数量少;
2.初始值是另一个 vector 对象的副本;
3.所有元素的初始值都一样;

但更一般的情况是:
1.创建一个 vector 对象时并不清楚实际所需要的元素个数,元素的值也无法确定;
2.或者元素的初始值已知,但是这些值的数量较大且各不相同。

更好的处理方法:
先创建一个空 vector,然后在运行时再利用 vector 的成员函数 push_back 向其中添加元素。
push_back 负责把一个值作为一个新的元素添加到 vector对象的后面,也就是“插入(push)”到 vector 对象的“后面(back)”:

vector<int> v2;	//空 vector 对象
for (int i = 0; i != 100; i++)
	v2.push_back(i);
//循环结束后 v2 有100个元素,值从0到99	

如果直到运行时才能知道 vector 对象中元素的确切个数:

//从标准输入中读取单词,将其作为 vector 对象的元素存储
string word;
vector<string> text;
while (cin >> word) {
	text.push_back(word);
}

三、其他 vector 操作

v.empty()如果 v 为空,则返回 true,否则返回 false
v.size()返回 v 中元素的个数
v.push_back(t)在 v 的末尾增加一个值为 t 的元素
v[n]返回 v 中位置为 n 的元素
v1 = v2用 v2 中元素的拷贝替换 v1 中的元素
v1 == v2v1 与 v2 相等当且仅当它们的元素数量相同且对应位置的元素值都相同
!=, <, <=,>, >=顾名思义,以字典顺序进行比较

访问 vector 对象中元素的方法和访问 string 对象中字符的方法差不多,通过元素在 vector 对象中的位置:

vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9};
for (auto &i : v)	//对于 v 中的每个元素(i 是一个引用)
	i *= i;	//求元素值得平方
for (auto i : v)	//对于 v 中的每个元素
	cout << i << " ";	//输出该元素
cout << endl;		

1.计算 vector 内对象的索引值

vector 对象的下标从 0 开始计起,下标的类型是相应的 size_type 类型。使用 size_type 类型时,必须指出该类型是在哪里定义的。vector 类型总是包括总是包括 vector 的元素类型:

vector<int>::size_type 	//正确 
vector::size_type 	//错误

只要 vector 对象不是一个常量,就能向下标运算符返回的元素赋值。此外,也可以通过计算得到 vector 内对象的索引,然后直接获取索引位置上的元素。

举个栗子:
有一组成绩的集合,成绩的取值是从 0 到 100。以 10 分为一个分数段,要求统计各个分数段各有多少个成绩。
在具体实现时使用一个含有 11 个元素的 vector 对象,每个元素分别用于统计各个分数段上出现的成绩个数。对于某个成绩来说,将其除以 10 就能得到相应的分数段索引。
==注意:两个整数相除,结果还是整数,余数部分被自动忽略掉了。==例如:42/10 = 4、65/10 = 6

//以 10 分为一个分数段统计成绩的数量:0~9,10~19,...,90~99,100
vector<unsigned> scores(11, 0); //11 个分段,全都初始化为0
unsigned grade;
while (cin >> grade) {	//读取成绩
	if (grade <= 100)	//只处理有效成绩
		++scores[grade / 10];	//将对应分数段的计数值加 1
}

2.不能以下标的形式添加元素

例如:为 vector 对象 ivec 添加 10 个元素:

vector<int> ivec; 	// 空 vector 对象
for (vector<int> :: size_type ix = 0; ix != 10; ++ix)
	ivec[ix] = ix;	//错误,ivec 不包含任何元素

正确方法:

for (vector<int> ::s ize_type ix = 0; ix != 10; ++ix)
	ivec.push_back(ix); // 正确:添加一个新元素,该元素的值是 ix

注意:vector 对象的下标运算符可用于访问已存在的元素,而不能用于添加元素
试图用下标去访问一个不存在的元素将引发错误,不过这种错误不会被编译器发现,而是在运行时产生一个不可预知的值。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值