C++标准库类型vector

本文介绍了C++标准库中的vector容器,详细阐述了vector的定义、初始化方式,包括列表初始化和按元素数量初始化。接着讨论了如何向vector中添加元素,以及push_back函数的使用。此外,文章还提到了访问和操作vector元素的方法,强调了不能通过下标直接添加元素。最后,文中给出了一些与vector操作相关的实践示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

这里是对c++标准库类型Vector的用法和相关操作的部分小结。


一、vector是什么?

标准库类型vector表示对象的集合 ,其中所有对象的类型都相同。集合中的每一个对象都有一个与之对应的索引,索引用于访问对象。由于vector“容纳着”其他对象,所以它常被称作容器(container)。

要想使用vector,必须包含适当的头文件。在后续的例子中都将假定做了如下using声明:

#include<vector>
using std::vector;

二、定义和初始化vector对象的方法

1.初始化vector对象

  • 定义和初始化vector对象
vector<T> v1;                   v1是一个空vector,它潜在的元素是T类型的,执行默认初始化
vector<T> v2(v1);               v2中包含有v1所有元素的副本
vector<T> v2 = v1;              等价于v2(v1),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...};        等价于v5{a,b,c...}
  • 实例带入
vector<int> v1;             //v1不含任何元素
vector<int> v1={1,2,3};     //v1中有3个元素,对应的值分别为1,2,3
vector<int> v2(v1);         //v2和v1相等
vector<int> v3(4,7);        //v3中有4个元素,每个元素的值都是7
vector<int> v4(5);          //v4有个元素,每个元素的值都是0

2.列表初始化vector对象

如果提供的是初始元素值得列表,则只能把初始值放在花括号里进行列表初始化,而不是放在圆括号里

vector<string> v1{"a","an","the"};  //列表初始化
vector<string> v2("a","an","the");  //错误
  • 创建指定数量的元素
vector<int> ivec(10,-1);        //10个int类型的元素,每个都被初始化为-1
vector<string> svec(10,"hi");   //10个string类型的元素没每个都被初始化为"hi"

3.区分列表初始值还是元素数量

1) int类型

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

2)string类型
想要列表初始化vector对象,花括号里的值必须与元素类型相同。显然不能用int初始化string对象,所以v7和v8提供的值不能作为元素的初始值。确认无法执行列表初始化后,编译器会尝试用默认值初始化vector对象。

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

三、对vector对象的操作

1.向vector对象中添加元素

如果想创建一个vector对象令其包含0 ~ 9共10个元素,使用列表初始化的方法很容易做到这一点;但如果vector对象包含的元素是从0 ~ 99 或者0 ~ 999,这时通过列表初始化把所有元素一一罗列出来就不太合适了。

数据量较大时,更好的处理方法是先创建一个空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的尾端

如果运行时才知道vector对象中元素的确切个数,也应该使用上述方法创建vector空对象并为其添加元素。
例如:有时需要实时读入数据然后将其赋予vector对象。

string word;
vector<string> text;       //空的vector对象
while(cin>>word){
     text.push_back(word); //把word添加到text后面
}

2.其他vector操作

除了push_back之外,vector还提供了几种其他操作。大多数都和string类型的相关操作类似。

v.empty();                如果v不含有任何元素,返回真(true);否则返回假(false)(返回值为布尔类型)
v.size();                 返回v中元素的个数
v[n]                      返回v中第n个位置上的元素的引用
v1 = v2                   用v2中元素的拷贝替换v1中的元素
v1 = {a,b,c...}           用列表中元素的拷贝替换v1中的元素
v1 == v2                  v1和v2相等当且仅当它们的元素数量相同且对应位置的元素值都相同
v1 != v2                  v1和v2不相等
<,<=,>,>=                 顾名思义,以字典顺序进行比较

访问vector对象中元素的方法和访问string对象中字符的方法差不多,也是通过元素在vector对象中的位置。
例如:可以使用范围for语句处理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中的每个元素(i的类型由auto关键字指定,同上)
 cout<<i<<" ";            //输出该元素

3.计算vector内对象的索引

使用下标运算符能获取到指定的元素。

通过例子能更好的理解:
假设有一组成绩的集合,其中成绩的取值是0~100。以10分为一个分数段,要求统计各个分数段各有多少个成绩。显然,从0到100总共有101种可能的成绩取值,这些成绩分布在11个分数段上:每10个分数构成一个分数段,这样的分数段有10个,额外还有一个分数段表示满分100分。这样第一个分数段将统计成绩在0到9之间的数量;第二个分数段将统计成绩在10到19之间的数量,以此类推。最后一个分数段统计满分100分的数量。

按照上述,如果输入的成绩如下:
42 65 95 100 39 67 95 76 88 76 83 92 76 93
则输出的结果应该是:
0 0 0 1 1 0 2 3 2 4 1

表示:30分以下没有人,30到39分数段1人,40到49分数段1人…(以此类推),最后一个表示有一个100分。

vector<unsigned> scores(11,0);     //11个分数段,全部初始化为0
unsigned grade;
while(cin>>grade){                 //读取成绩
     if(grade<=100)                //只处理有效成绩
       ++scores[grade/10];         //将对应分数段的计数值加1(将分数/10就得到分数所在的分数段)
}

4.不能用下标形式添加元素

vector<int> ivec;        //空vector对象
for(decltype(ivec.size()) ix=0;ix!=10;++ix)      //decltype(x)用于识别x的类型并返回该类型
    ivec[ix] = ix;       //严重错误:ivec不包含任何元素
    ivec.push_back(ix);  //正确:添加一个新元素,该元素的值是ix

注意1:vector对象(以及string对象)的下标运算符可用于访问已存在的元素,而不能用于添加元素

注意2:确保下标合法(不越界、不溢出)的一种有效手段就是尽可能使用范围for语句


四、总结

相关实例

1)从cin读入一组词并把它们存入一个vector对象,然后设法把所有词都改写为大写形式。输出改变后的结果,每个词占一行。

#include<iostream>
#include<vector>
using namespace std;
int main() {
	vector<string> ivet;
	string s;
	while (cin >> s) {
		if (s == "no")
			break;
		ivet.push_back(s);
	}
	for (string &x : ivet) {//引用型才能够容器中修改原来的值
		for(char &c:x)
			c = toupper(c);
		cout << x << " ";
	}
	return 0;
}

2)读入一组整数并把它们存入一个vector对象,先输出第1个和最后1个元素的和,接着输出第2个和倒数第2个元素的和,以此类推。

#include<iostream>
#include<vector>
using namespace std;
int main() {
	vector<int> ivec;
	int x,i = 0;
	while (cin >> x) {         //以0作为输入的结束符
		if (x == 0)
			break;
		ivec.push_back(x);
	}
	for (i = 0; i < ivec.size()/2; i++) {
		cout << ivec[i] + ivec[ivec.size()-1-i] << " ";
	}
	if (ivec.size() % 2 == 1)  //若输入的数据个数为奇数,最后将输出中间的数
		cout << ivec[i];
	return 0;
} 

3)读入一组整数并把它们存入一个vector对象,将每对相邻整数的和输出出来。

#include<iostream>
#include<vector>
using namespace std;
int main() {
	vector<int> ivec;
	int x, i = 0;
	while (cin >> x) {         //以0作为输入的结束符
		if (x == 0)
			break;
		ivec.push_back(x);
	}
	if (ivec.size() == 0) {    
		cout << "没有元素";
		return -1;
	}
	for (i = 0; i < ivec.size()-1; i+=2) {   //相邻两两一对,不重复
		cout << ivec[i] + ivec[i+1] << " ";
	}
	if (ivec.size() % 2 == 1)  //若输入的数据个数为奇数,对最后一个元素单独处理
		cout << ivec[ivec.size() - 1];
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值