标准库类型vector的常用的定义初始化与输出方法

本文详细介绍了C++标准库中的vector容器,包括其概念、动态调整大小、优点(如随机访问和管理便利)、局限性(如插入删除开销和内存管理),并涵盖了定义、初始化、元素操作和常用方法等内容。
摘要由CSDN通过智能技术生成

 

目录

 

一:vector的概念

二:vector的优点和局限性

(1)优点

(2)局限性

三:vector的定义与初始化

(1)一维向量

(2)二维向量

①vector vec[N]类型

②vector>  vec类型

四:vector中的元素的输出

五:vector常用方法


一:vector的概念

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

    术语:何为对象? 根据<<C++primer>>C++11标准解释是这样的:认为对象是具有某种数据类型的内存空间,并不严格区分是类还是内置类型,也不区分是否命名或者是否只读。               

二:vector的优点和局限性

(1)优点

①动态大小:vector 具有动态分配内存的能力,可以根据需要动态增加或减少元素的数量,而不需要预先指定大小。
②随机访问:vector 支持常量时间的随机访问,这意味着可以直接通过索引访问元素,而不受向量大小的影响。
③管理方便:std::vector 提供了许多方便使用的函数,这些函数可以方便地对向量进行访问、修改、插入、删除等操作,这也是算法竞赛中常用原因。

(2)局限性

①插入和删除操作开销较大:在向量的中间插入或删除元素会导致其他元素的移动,因此时间复杂度是 O(n),其中 n 是向量的大小。如果进行插入操作时,如果当前容量不足,vector 需要重新分配内存以扩展容量,并将原有的元素拷贝到新的内存空间中。
②不适合大规模数据:由于连续存储的特性,当向量的大小变得非常大时,可能会导致内存分配失败或者频繁的内存重新分配,影响性能。
③不支持快速查找和删除操作:与哈希表或平衡二叉树相比,vector 不适合频繁的查找和删除操作,因为这些操作的时间复杂度较高。
④不适合存储大对象:由于连续存储的特性,向量存储大对象时可能会导致内存碎片化,增加内存开销。

三:vector的定义与初始化

(1)一维向量

vector<数据类型> 名字
vector<T> vec          定义一个T数据类型的空vector元素,执行默认初始化,有些类型不支持默认初始化
vector<T> vec(n,val)   定义n个T数据类型的元素,每个元素的值为val
vector<T> vec(n)       定义n个T数据类型的元素,执行默认初始化,有些类型不支持默认初始化
vector<T> vec{a,b,c...}vec中每个元素被赋予相应的初始值
vector<T> vec={a,b,c...}等价于vec{a,b,c...}
vector<T> vec2(vec1)   vec2中包含有vec1所有元素的副本,把vec1中的元素拷贝给vec2
vector<T> vec2=vec1    等价于vec2(vec1),注意vec2与vec1必须具有相同的数据类型

 

初始化时注意以下细节:

1.初始化vector对象的时候花括号,圆括号,中括号有区别:
vector<string> vec={"Welcome","to","C++"};//正确,列表初始化
vector<string> vec=("Welcome","to","C++");//错误

vector<int> vec(10);//vec有10个元素,每个值为0
vector<int> vec{10};//vec有一个元素,其值为10
vector<int> v=10;//这种初始化是错误的
vector<T>  vec[10];//这是个向量组,相等于二维动态数组,后面有讲

vector<int> v1(10,1);//v1中有10个元素,每个元素值为1
vector<int> v2{10,1};//v2中有2个元素,其值分别是10,1

2.此外对于vector<T> vec(n) 这种初始化有一些特殊限制;
其一:对于基本数据类型,可能是未定义的值(可能是0或者其他垃圾值,取决于编译器),
对于类类型,可能是默认构造函数初始化的值。
其二:有些类型不支持默认初始化,则必须提供初始元素值,
比如当T是一个不可默认构造的类型,那么这种初始化将会导致编译错误。

注意:对于使用 vector<int> vec(n) 这样初始化的向量 vec,vec 的大小已经固定为 n,并且其中的元素已经被初始化了。在这种情况下,使用 push_back() 方法来添加新的元素的时候,会在向量的末尾添加一个新的元素,这个末尾什么意思呢?以下有段代码可以演示。

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	int n=5;
	vector<int> vec(n);
	vec.push_back(6);
	for (int i = 0; i <= 5; i++)  cout << vec[i];
	return 0;
}

 vector<int> vec(n);这一句会执行初始化,vec里面全是0,那么输出是什么?

000006

没错!就是000006,它会在添加6在向量末尾(伴随一个扩容操作)。

(2)二维向量

假如声明一个常量N

①vector<T> vec[N]类型

它是一个向量组,动态数组的个数确定,每个动态数组个数不确定,可自由添加或删除元素。

②vector<vector<T>>  vec类型

每个维度都可以变,动态数组个数可自由变化,每个动态数组的元素也可自由变化。

如果想要初步固定两个维度长度,可以这么初始化。

vector<vector<int>> vec(n, vector<int>(n, 0)); // 创建一个 n 个长度为 n 的二维向量,并将所有元素初始化为 0

其它维度暂时不举例了。

四:vector中的元素的输出

1.vector支持下标运算符,把vector理解为动态数组:

例如1)int类型:

vector<int> a{5,2,1};
for (int i = 0; i < 3; i++)
	cout << a[i]<<" ";

输出:

5 2 1

2)char类型:

int n;
cin >> n;
vector<char> b(n, '.');
for (int i = 0; i < n; i++)
    cin >> b[i];
for (int i = 0; i < n; i++)
	cout << b[i]<<" ";

输入:

6
A B C D E F

输出:

A B C D E F

3)string类型

vector<string> c(n);
for (int i = 0; i < n; i++)
	cin >> c[i];
for (int i = 0; i < n; i++)
	cout << c[i] <<" ";
	

输入:

3
Hello!
C++
Program.

输出:

Hello! C++ Program.

剩下的数据类型就不举例了。

2.可以使用范围for语句处理vector对象中的所有元素,访问vector对象中的元素方法和访问string对象中的字符方法差不多,也是通过元素在vector对象中的位置。vector对象(以及string对象)的下标运算符号可以用于访问已存在的元素,而不能用于添加元素。添加元素可以用vec.push_back(t)函数(向vec尾端添加一个值为t的元素)

vector<int> vec{ 1,2,3,4,5,6,7,8,9 };
for (auto& i : vec)//i是一个引用,类似于别名,但有区别!
	i *= i;//求元素值的平方
for (auto i : vec)
	cout << i << " ";

输出:

1 4 9 16 25 36 49 64 81

 3.使用迭代器。除了vector之外,标准库还定义了其他几种容器,所有标准库容器都可以使用迭代器,但是其中只有少数几种才同时支持下标运算符。

vector<char> s{ 'a','b','c','d','e' };
for (auto it = s.begin(); it != s.end(); it++)//迭代器类型为vector<char>::iterator it;
{
	*it = toupper(*it);
	cout << *it;
}
//可以改写为for (vector<char>::iterator it = s.begin(); it != s.end(); it++),auto可以让编译器自己判断迭代器类型

输出:

ABCDE

4.使用标准库算法std::for_each()来遍历容器,定义在头文件<algorithm>中,STL算法中for_each, for_each算法很常用,值得深入学习一下,很灵活。

vector<int> v{ 1,2,3,4,5 };
auto print = [](int i) { cout << i << " "; };
for_each(v.begin(), v.end(), print);

还可以这样写:

for_each(v.begin(), v.end(), [](int i){cout << i << " ";});

输出都是:

1 2 3 4 5

剩下的输出方法后续再补充...

五:vector常用方法

(1)访问元素
operator[]:通过索引访问向量中的元素。
at():通过索引访问向量中的元素,提供范围检查。
(2)容量操作
size():返回向量中的元素数量。
empty():检查向量是否为空。
capacity():返回向量当前的容量。
reserve():请求向量预留额外的存储空间。
shrink_to_fit():请求向量释放多余的存储空间。
(3)修改操作
push_back():在向量末尾添加一个元素。
pop_back():从向量末尾删除一个元素。
insert():在指定位置插入一个或多个元素。
erase():删除指定位置的一个或多个元素。
clear():清空向量中的所有元素。
(4)元素操作
front():返回向量中第一个元素的引用。
back():返回向量中最后一个元素的引用。
assign():用新值替换向量中的元素。
swap():交换两个向量的内容。
(5)查找
find():查找指定值在向量中的位置。
count():统计指定值在向量中出现的次数。
(6)迭代器
begin():返回指向第一个元素的迭代器。
end():返回指向最后一个元素之后的迭代器。

更新日志:

2023.5.22《C++primer》vector学习flag

2024.5.10 0:44 睡不着,起来更新vector的优缺点和维度问题,概述常用方法,有人看再更......

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值