C++ vector基本操作

这篇具有很好参考价值的文章主要介绍了C++ vector基本操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、介绍

二、定义

三、迭代器

四、容量操作

1、size

2、capacity

3、empty

4、resize

5、reserve

总结(扩容机制)

五、增删查改

1、push_back & pop_back

2、find

3、insert

4、erase

5、clear

6、swap

7、operator[]


一、介绍

vector的文档介绍

  1. vector是表示可变大小数组的序列容器。
  2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
  3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
  4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
  5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
  6. 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list统一的迭代器和引用更好。

vector的使用

vector学习时一定要学会查看文档:vector的文档介绍,vector在实际中非常的重要,在实际中我们熟悉常见的接口就可以。

二、定义

C++ vector基本操作,C++,c++,开发语言

这些是C++标准库中`vector`类的构造函数的不同重载形式。下面是对每个构造函数的解释:

1. 无参构造函数:`vector()` 

vector<int> v;
  • 创建一个空的`vector`对象,不包含任何元素。

2. 构造并初始化n个val:`vector(size_type n, const value_type& val = value_type())`

vector<int> v1(10, 1);
  • 创建一个包含`n`个元素的`vector`对象,每个元素都初始化为`val`。
  • 可以选择提供一个初始值`val`,如果未提供,则使用默认值类型的默认构造函数进行初始化。

3. 使用迭代器进行初始化构造 :`vector(InputIterator first, InputIterator last)`

string s1("hello");
vector<char> v3(s1.begin(), s1.end());
  • 创建一个`vector`对象,并使用范围 `[first, last)` 内的元素进行初始化。
  • `first` 和 `last` 是迭代器,指定了要复制的元素范围。
  • 这个构造函数允许使用迭代器来指定要复制的元素范围,可以是数组、容器或其他可迭代对象。

4. 拷贝构造函数:`vector(const vector& x)` 重点

vector<int>v1(v);
  • 创建一个新的`vector`对象,其元素与另一个`vector`对象`x`相同。
  • 拷贝构造函数用于创建一个副本,新的`vector`对象将独立于原始对象,对其中一个对象的修改不会影响另一个对象。

举例演示一下,其中输出和string类一样,有三种方式:范围for [ ] 迭代器。

void test1()
{
	//无参构造
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);

	//三种输出方式 范围for [] 迭代器
	for (auto a : v)
	{
		cout << a << " ";
	}
	cout << endl;

	for (size_t i = 0; i < v.size(); i++)
	{
		cout << v[i] << " ";
	}
	cout << endl;

	//vector<int>::iterator it = v.begin();
	auto it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	
	//拷贝构造
	vector<int> copy(v);
	for (auto a : copy) 
	{
		cout << a << " ";
	}
	cout << endl;
}
void test2()
{
	//构造并初始化
	vector<int> v1(6, 6);
	for (auto a : v1)
	{
		cout << a << " ";
	}
	cout << endl;

	//迭代器
	vector<int> v2(v1.begin(), v1.end());
	for (auto b : v2)
	{
		cout << b << " ";
	}
	cout << endl;

	string s1("hello");
	vector<char> v3(s1.begin(), s1.end());
	for (auto b : v3)
	{
		cout << b << " ";
	}

}
int main()
{
	test1();
    cout << endl;
    test2();
	return 0;
}

C++ vector基本操作,C++,c++,开发语言

三、迭代器

C++ vector基本操作,C++,c++,开发语言

begin()/end()获取第一个数据位置的iterator / const_iterator, 获取最后一个数据的下一个位置的iterator / const_iterator

rbegin()/rend()获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的reverse_iterator

通过使用这些接口,可以在vector中进行迭代操作。

  • 例如,使用begin()end()可以遍历vector中的元素,而使用rbegin()rend()可以反向遍历vector中的元素。
  • 请注意,对于只读的vector,应使用const_iteratorconst_reverse_iterator来确保不修改vector的元素。
void test3()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
    //正向迭代器
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
    //反向迭代器
	vector<int>::reverse_iterator rit = v.rbegin();
	while (rit != v.rend())
	{
		cout << *rit << " ";
		++rit;
	}
}
int main()
{
    test3();
    return 0;
}

C++ vector基本操作,C++,c++,开发语言

四、容量操作

1、size

获取数据个数。
int main() {
    std::vector<int> v = {1, 2, 3, 4, 5};
    std::cout << "Size of vector: " << v.size() << std::endl;
    return 0;
}
C++ vector基本操作,C++,c++,开发语言

2、capacity

capacity获取容量大小。
int main() {
    std::vector<int> v;
    std::cout << "Initial capacity: " << v.capacity() << std::endl;
    for (int i = 0; i < 10; i++) {
        v.push_back(i);
        std::cout << "Capacity after pushing " << i << ": " << v.capacity() << std::endl;
    }
    return 0;
}
C++ vector基本操作,C++,c++,开发语言

3、empty

判断是否为空。
int main() {
    std::vector<int> v;
    std::cout << "Is vector empty? " << (v.empty() ? "Yes" : "No") << std::endl;
    v.push_back(1);
    std::cout << "Is vector empty? " << (v.empty() ? "Yes" : "No") << std::endl;
    return 0;
}

C++ vector基本操作,C++,c++,开发语言

4、resize

改变vector的size。
void resize (size_type n, value_type val = value_type());
  1. 调整容器的大小,使其包含 n 个元素。
  2. 如果 n 小于当前容器大小,则内容将减少到其前 n 个元素,删除超出的元素(并销毁它们)。
  3. 如果 n 大于当前容器大小,则通过在末尾插入任意数量的元素来扩展内容,以达到 n 的大小。如果指定了 val,则新元素将初始化为 val 的副本,否则,它们将初始化值。
  4. 如果 n 也大于当前容器容量,则会自动重新分配分配的存储空间。
  5. 请注意,此函数通过插入或擦除容器中的元素来更改容器的实际内容。
int main() {
    std::vector<int> v = {1, 2, 3, 4, 5};
    v.resize(7, 100);
    for (int i : v) {
        std::cout << i << " ";
    }
    std::cout << std::endl;
    v.resize(3);
    for (int i : v) {
        std::cout << i << " ";
    }
    return 0;
}

C++ vector基本操作,C++,c++,开发语言

5、reserve

改变vector的capacity。
reserve(): 这个方法更改vector的capacity。如果新的capacity大于当前的capacity,那么vector的内存将被重新分配以适应更多的元素。如果新的capacity小于当前的capacity,那么这个方法不会有任何效果。
int main() {
    std::vector<int> v;
    std::cout << "Initial capacity: " << v.capacity() << std::endl;
    v.reserve(10);
    std::cout << "Capacity after reserving: " << v.capacity() << std::endl;
    return 0;
}
C++ vector基本操作,C++,c++,开发语言

总结(扩容机制)

  • capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的
  • 这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。
  • reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。
  • resize在开空间的同时还会进行初始化,影响size。

通过下面代码可以观察到vector的默认扩容机制。

void TestVectorExpand()
{
	size_t sz;
	vector<int> v;
	sz = v.capacity();
	cout << "making v grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

C++ vector基本操作,C++,c++,开发语言

如果已经确定vector中要存储元素大概个数,可以提前将空间设置足够就可以避免边插入边扩容导致效率低下的问题了。

void TestVectorExpandOP()
{
	vector<int> v;
	size_t sz = v.capacity();
	v.reserve(100); // 提前将容量设置好,可以避免一遍插入一遍扩容
	cout << "making bar grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

C++ vector基本操作,C++,c++,开发语言

五、增删查改

1、push_back & pop_back

尾插&尾删
int main() {
	std::vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	for (int i : v) {
		std::cout << i << " ";
	}
	cout << endl;
	v.pop_back();
	for (int i : v) {
		std::cout << i << " ";
	}
	return 0;
}

2、find

template <class InputIterator, class T>
InputIterator find (InputIterator first, InputIterator last, const T& value);

使用find函数的步骤如下:

  1. 确定要搜索的范围,将范围的起始位置和结束位置作为参数传递给find函数。通常,起始位置是容器的开始迭代器,结束位置是容器的结束迭代器。

  2. 指定要查找的值,作为第三个参数传递给find函数。

  3. 调用find函数,并将返回的迭代器存储在一个迭代器变量中。

  4. 检查返回的迭代器是否等于结束迭代器,以确定是否找到了指定值的元素。如果返回的迭代器等于结束迭代器,则表示未找到指定值的元素;否则,表示找到了指定值的元素

  • 例如,如果有一个vector v,可以使用std::find(v.begin(), v.end(), 5)在v中查找整数5。

3、insert

single element (1)	
    iterator insert (iterator position, const value_type& val);

fill (2)	
    void insert (iterator position, size_type n, const value_type& val);

range (3) template <class InputIterator>
    void insert (iterator position, InputIterator first, InputIterator last);
  1. 单个元素插入 (1): iterator insert (iterator position, const value_type& val); 这个重载函数用于在指定位置之前插入一个单个元素。它接受两个参数,第一个参数是一个迭代器,表示插入位置,第二个参数是要插入的元素的值。返回一个迭代器,指向插入的元素。

  2. 填充插入 (2): void insert (iterator position, size_type n, const value_type& val); 这个重载函数用于在指定位置之前插入多个相同的元素。它接受三个参数,第一个参数是一个迭代器,表示插入位置,第二个参数是要插入的元素的个数,第三个参数是要插入的元素的值。没有返回值。

  3. 范围插入 (3): template <class InputIterator> void insert (iterator position, InputIterator first, InputIterator last); 这个重载函数用于在指定位置之前插入一个范围内的元素。它接受三个参数,第一个参数是一个迭代器,表示插入位置,第二个参数和第三个参数是表示范围的迭代器,用于指定要插入的元素范围。可以是任何类型的迭代器,例如指向数组、容器或者其他序列的迭代器。没有返回值。

#include <iostream>
#include <vector>
#include <array>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::array<int, 3> arr = {10, 11, 12};

    // 单个元素插入
    numbers.insert(numbers.begin() + 2, 10);

    // 填充插入
    numbers.insert(numbers.begin() + 4, 3, 7);

    // 范围插入
    numbers.insert(numbers.end(), arr.begin(), arr.end());

    // 输出插入后的向量
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

C++ vector基本操作,C++,c++,开发语言

4、erase

iterator erase (iterator position);
iterator erase (iterator first, iterator last);
  • 删除 erase函数用于删除指定位置的元素。它需要提供要删除的位置作为参数,并返回一个指向被删除元素之后位置的迭代器。
#include <iostream>
#include <vector>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // 删除第三个元素
    std::vector<int>::iterator it1 = numbers.erase(numbers.begin() + 2);

    // 删除第二个到第四个元素
    std::vector<int>::iterator it2 = numbers.erase(numbers.begin() + 1, numbers.begin() + 4);

    // 输出删除后的向量
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

C++ vector基本操作,C++,c++,开发语言

5、clear

void clear();
  • 这个函数用于删除向量中的所有元素,使向量变为空。
#include <iostream>
#include <vector>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // 删除第三个元素
    numbers.erase(numbers.begin() + 2);

    // 删除第二个到第四个元素
    numbers.erase(numbers.begin() + 1, numbers.begin() + 4);

    // 清空整个向量
    numbers.clear();

    return 0;
}

6、swap

  • 交换 swap函数用于交换两个vector的数据空间。它需要提供另一个vector作为参数,并将当前vector的内容与参数vector的内容进行交换。
  • 例如,如果有两个vector v1和v2,可以使用v1.swap(v2)交换它们的内容。
int main() {
	std::vector<int> v1 = { 1, 2, 3 };
	std::vector<int> v2 = { 4, 5, 6 };
	v1.swap(v2);
	for (int i : v1) {
		cout << i << " ";
	}
	cout << endl;
	for (int i : v2) {
		cout << i << " ";
	}
	return 0;
}

C++ vector基本操作,C++,c++,开发语言

7、operator[]

像数组一样访问

int main()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	for (size_t i = 0; i < v.size(); ++i)
	{
		cout << v[i] << " ";
	}

	return 0;
}

C++ vector基本操作,C++,c++,开发语言文章来源地址https://www.toymoban.com/news/detail-758833.html

到了这里,关于C++ vector基本操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • go语言基本操作---三

    指针是一个代表着某个内存地址的值。这个内存地址往往是在内存中存储的另一个变量的值的起始位置。Go语言对指针的支持介于java语言和C/C+语言之间,它即没有想Java语言那样取消了代码对指针的直接操作的能力,也避免了C/C+语言中由于对指针的滥用而造成的安全和可靠性

    2024年02月09日
    浏览(33)
  • R语言——基本操作(一)

    目录 一、基本操作 二、R包的安装及使用 三、获取帮助 四、内置数据集 五、数据结构 六、向量索引 七、向量运算 参考 Rstudio 控制台常用快捷键 Ctrl + ↑ : 查看所有历史记录,比直接使用 ↑ 查找更方便 Esc: 中断操作,可中断未完成的操作(未完成回车后是 + ),也可以

    2024年04月15日
    浏览(21)
  • 链表的基本操作(c语言)

    目录 链式存储结构 代码实现 链表初始化 头插法(前插法)创建含k个结点的单链表 尾插法(后插法)创建含k个结点的单链表 取第i个节点的数据域 寻找数据域等于e的结点返回该结点序号 在第i个结点插入数据域为e的结点 删除第i个结点 遍历链表 求链表结点个数(链表长度) 销毁

    2024年02月08日
    浏览(34)
  • 栈的概念及其基本操作--详细(C++)

    基本概念及相关术语: 栈是只允许 在一端 进行插入和删除操作的 线性表 。 由此可见,栈也是线性表的一种,只是栈的操作受限制的线性表。 栈顶(top):线性表允许插入和删除的那一段。 值得注意的是,栈顶指针top的指向是有些两种方式的,一种是指向栈顶当前元素,

    2024年02月08日
    浏览(27)
  • C语言实现链表基本操作

    目录 一、什么是链表 二、为什么要使用链表 三、链表相关知识 四、链表实现 1.定义结构体 2.创建链表 3.遍历链表 4.判断链表是否为空 5.计算链表长度 6.插入一个数据 7.删除数据 8.全部代码 如果把数据比喻成珠子,指针就是线,链表通过指针这条线就是把数据这些珠子串起

    2024年02月06日
    浏览(32)
  • 数据结构——单链表基本操作实现 (c++)

    单链表链式存储结构的特点是:用一组任意的存储单元存储线性表的数据元素(这里存储单元可以是连续的,也可以是不连续的),为了表示每个数据元素a与其直接后继数据元素之间的逻辑关系,除了存储信息本身外还要存储一个指示其直接后继的信息(地址). 这两部分信

    2024年02月03日
    浏览(42)
  • 【C++】单链表——单链表的基本操作

     由于顺序表的插入删除操作需要移动大量的元素,影响了运行效率,因此引入了线性表的链式存储—— 单链表 。单链表通过一组任意的存储单元来存储线性表中的数据元素,不需要使用地址连续的存储单元,因此它不要求在逻辑上相邻的两个元素在物理位置上也相邻。 单

    2024年02月03日
    浏览(35)
  • 【c++】 list容器的基本操作与接口

    List容器是一个双向链表。 采用动态存储分配,不会造成内存浪费和溢出 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素 链表灵活,但是空间和时间额外耗费较大 list构造函数 list数据元素插入和删除操作 list大小操作 list赋值操作 l ist数据的存取 li

    2024年02月17日
    浏览(38)
  • 顺序表基本操作算法——基础代码(C语言)

     创建一个顺序表(数据元素个数为5), 输出顺序表中的所有数据元素 查找第3个位置上的元素 查找元素15是否在顺序表中,如果在,请输出该元素在顺序表中的位置 在顺序表中的第1个位置插入数据0 删除刚刚插入的元素 输出顺序表中的所有数据元素 运行结果如下  

    2024年02月06日
    浏览(37)
  • C语言第十一课--------操作符的使用与分类-------基本操作

             作者介绍:           作者id : 老秦包你会 , 简单介绍:              喜欢学习C语言和python等编程语言,是一位爱分享的博主,有兴趣的小可爱可以来互讨                                 个人主页::小小页面                                   gitee页面

    2024年02月14日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包