C++ vector详解


一、vector介绍

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
在这里插入图片描述
翻译:vector是序列式容器,表示可以改变大小的数组。
就像数组一样,向量为其元素使用连续的存储位置,这意味着也可以使用指向其元素的常规指针上的偏移量来访问其元素,并且与数组中一样高效。但与array不同的是,它们的大小可以动态变化,其存储由容器自动处理。

  vector构造

在这里插入图片描述
代码验证:

// constructing vectors
#include <iostream>
#include <vector>

void ShowVectorValues(std::vector<int>& vec);

int main()
{
	std::vector<int> first;        // 创建一个空的vector容器
	std::vector<int> second(4, 100);    // 包含四个值为100的元素
	std::vector<int> third(second.begin(), second.end());
	std::vector<int> fourth(third);

	// the iterator constructor can also be used to construct from arrays:
	int myints[] = { 16,2,77,29 };
	std::vector<int> fifth(myints, myints + sizeof(myints) / sizeof(int));

	std::cout << "打印容器first内元素:";
	ShowVectorValues(first);

	std::cout << "打印容器second内元素:";
	ShowVectorValues(second);

	std::cout << "打印容器third内元素:";
	ShowVectorValues(third);

	std::cout << "打印容器fourth内元素:";
	ShowVectorValues(fourth);

	std::cout << "打印容器fifth内元素:";
	ShowVectorValues(fifth);

	return 0;
}

void ShowVectorValues(std::vector<int>& vec)
{
	for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
		std::cout << ' ' << *it;
	}
	std::cout << '\n';
}

运行结果:
在这里插入图片描述

二、增删改查

  vector插入

    push_back

在这里插入图片描述
代码验证:

// vector::push_back
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> myvector;
    myvector.push_back(1);
    myvector.push_back(2);
    myvector.push_back(3);
    myvector.push_back(4);

    std::cout << "myvector中元素个数:" << myvector.size() << std::endl;
    std::cout << "打印容器myvector内元素:";
    for (auto item : myvector) {
        std::cout << item << " ";
    }
    return 0;
}

运行结果:
在这里插入图片描述

    insert

在这里插入图片描述
代码验证:

// inserting into a vector
#include <iostream>
#include <vector>
using namespace std;

void ShowVectorValues(vector<int>& vec);

int main()
{
    vector<int> myvector(3, 100);
    cout << "当前容器包含元素:";
    ShowVectorValues(myvector);

    vector<int>::iterator it;
    it = myvector.begin();
    it = myvector.insert(it, 200);
    cout << "调用myvector.insert(it, 200)后:";
    ShowVectorValues(myvector);

    myvector.insert(it, 2, 300);
    cout << "调用myvector.insert(it, 2, 300)后:";
    ShowVectorValues(myvector);

    // "it" no longer valid, get a new one:
    it = myvector.begin();
    vector<int> anothervector(2, 400);
    myvector.insert(it + 2, anothervector.begin(), anothervector.end());
    cout << "调用myvector.insert(it + 2, anothervector.begin(), anothervector.end())后:";
    ShowVectorValues(myvector);

    int myarray[] = { 501,502,503 };
    myvector.insert(myvector.begin(), myarray, myarray + 3);
    cout << "调用myvector.insert(myvector.begin(), myarray, myarray + 3)后:";
    ShowVectorValues(myvector);

    return 0;
}

void ShowVectorValues(vector<int>& vec)
{
    for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
        cout << ' ' << *it;
    }
    cout << '\n';
}

运行结果:
在这里插入图片描述

  vector删除

    pop_back

在这里插入图片描述
代码验证:

// vector::pop_back
#include <iostream>
#include <vector>
using namespace std;

void ShowVectorValues(vector<int>& vec);

int main()
{
    std::vector<int> myvector = {100, 200, 300};

    cout << "当前容器包含元素:";
    ShowVectorValues(myvector);

    myvector.pop_back();
    cout << "调用一次pop_back()后:";
    ShowVectorValues(myvector);

    myvector.pop_back();
    cout << "调用两次pop_back()后:";
    ShowVectorValues(myvector);
    return 0;
}

void ShowVectorValues(vector<int>& vec)
{
    for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
        cout << ' ' << *it;
    }
    cout << '\n';
}

运行结果:
在这里插入图片描述

    erase

在这里插入图片描述
代码验证:

// erasing from vector
#include <iostream>
#include <vector>
using namespace std;

void ShowVectorValues(vector<int>& vec);

int main()
{
    vector<int> myvector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    cout << "当前容器包含元素:";
    ShowVectorValues(myvector);

    // 移除第六个元素
    myvector.erase(myvector.begin() + 5);
    cout << "调用myvector.erase(myvector.begin() + 5)后:";
    ShowVectorValues(myvector);

    // 移除前面三个元素
    myvector.erase(myvector.begin(), myvector.begin() + 3);
    cout << "调用myvector.erase(myvector.begin(), myvector.begin() + 3)后:";
    ShowVectorValues(myvector);
    return 0;
}

void ShowVectorValues(vector<int>& vec)
{
    for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
        cout << ' ' << *it;
    }
    cout << '\n';
}

运行结果:
在这里插入图片描述

    clear

在这里插入图片描述
代码验证:

// erasing from vector
#include <iostream>
#include <vector>
using namespace std;

void ShowVectorValues(vector<int>& vec);

int main()
{
    vector<int> myvector = {1, 2, 3, 4, 5};
    cout << "当前容器包含元素:";
    ShowVectorValues(myvector);
    cout << "当前容器size:" << myvector.size() << endl;

    // 调用clear()
    myvector.clear();
    cout << "调用clear()后:";
    ShowVectorValues(myvector);
    cout << "调用clear()后size:" << myvector.size() << endl;
    return 0;
}

void ShowVectorValues(vector<int>& vec)
{
    for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
        cout << ' ' << *it;
    }
    cout << '\n';
}

在这里插入图片描述

  vector修改

    operator[ ]

在这里插入图片描述
翻译:返回对向量容器中位置n处元素的引用。
类似的成员函数vector::at与此运算符函数具有相同的行为,不同之处在于vector::at已进行绑定检查,并通过抛出out_of_range异常来发出请求位置是否超出范围的信号
代码验证:

// vector::operator[]
#include <iostream>
#include <vector>
using namespace std;

void ShowVectorValues(vector<int>& vec);

int main()
{
    vector<int> myvector = { 1, 2, 3, 4, 5 };
    cout << "当前容器包含元素:";
    ShowVectorValues(myvector);

    cout << "myvector[0]:" << myvector[0] << endl;
    cout << "myvector[1]:" << myvector[1] << endl;
    cout << "myvector[2]:" << myvector[2] << endl;
    cout << "myvector[myvector.size() - 1]:" << myvector[myvector.size() - 1] << endl;
    myvector[2] = 100;
    cout << "修改myvector[2]后容器包含元素:";
    ShowVectorValues(myvector);
    return 0;
}

void ShowVectorValues(vector<int>& vec)
{
    for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
        cout << ' ' << *it;
    }
    cout << '\n';
}

运行结果:
在这里插入图片描述

  vector查找

    find

vector本身没有find这一方法,依靠algorithm中find来实现查找容器中元素
在这里插入图片描述

代码验证:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main()
{
    vector<int> vec = {1, 2, 3, 4, 5};
    vector<int>::iterator it = find(vec.begin(), vec.end(), 2); // 目标值2在容器中的下标为1

    if (it != vec.end()) {
        cout << "输出目标值的下标: " << it - vec.begin() << endl;
    }
    return 0;
}

运行结果:
在这里插入图片描述

    sort

vector本身没有sort这一方法,依靠algorithm中sort来实现排序容器中元素
在这里插入图片描述
翻译:按升序对范围[第一个,最后一个)中的元素进行排序。
第一个版本使用运算符<比较元素,第二个版本使用comp比较元素。
等效元素不能保证保持其原始相对顺序

代码验证:

// sort algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector

bool myfunction(int i, int j) { return (i < j); }

struct myclass {
    bool operator() (int i, int j) { return (i < j); }
} myobject;

int main() {
    int myints[] = { 32,71,12,45,26,80,53,33 };
    std::vector<int> myvector(myints, myints + 8);               // 32 71 12 45 26 80 53 33

    // using default comparison (operator <):
    std::sort(myvector.begin(), myvector.begin() + 4);           //(12 32 45 71)26 80 53 33

    // using function as comp
    std::sort(myvector.begin() + 4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)

    // using object as comp
    std::sort(myvector.begin(), myvector.end(), myobject);     //(12 26 32 33 45 53 71 80)

    // print out content:
    std::cout << "myvector contains:";
    for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;
}

运行结果:
在这里插入图片描述

三、vector常见成员函数

    empty

在这里插入图片描述
代码验证:

// vector::empty
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> vec = {1, 2, 3, 4, 5};
    if (vec.empty()) {
        cout << "当前vector容器  空" << endl;
    }
    else {
        cout << "当前vector容器  非空" << endl;
    }
    cout << "当前vector容器的size: " << vec.size() << endl;

    vec.clear();

    if (vec.empty()) {
        cout << "调用clear后  空" << endl;
    }
    else {
        cout << "调用clear后  非空" << endl;
    }
    cout << "调用clear后size: " << vec.size() << endl;
    return 0;
}

运行结果:
在这里插入图片描述

    size

在这里插入图片描述
代码验证:

// vector::size
#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<int> myints;
	cout << "空容器初始size: " << myints.size() << endl;

	for (int i = 0; i < 10; i++) myints.push_back(i);
	cout << "调用10次push_back后size: " << myints.size() << endl;

	myints.pop_back();
	cout << "调用一次pop_back后size: " << myints.size() << endl;
	return 0;
}

运行结果:
在这里插入图片描述

    capacity

在这里插入图片描述
翻译:
返回当前分配给vector的存储空间的大小,以元素表示。
该容量不一定等于vector大小size。它可以相等或更大,额外的空间可以容纳增长,而无需在每次插入时重新分配。
请注意,此容量不假定vector大小有限制。当这个容量用完并且需要更多时,容器会自动扩展它(重新分配存储空间)。vector大小的理论限制由成员max_size给出。
可以通过调用成员vector::reserve来显式地更改向量的容量。

代码验证:

// comparing size, capacity and max_size
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector;

  // set some content in the vector:
  for (int i=0; i<100; i++) myvector.push_back(i);

  std::cout << "size: " << (int) myvector.size() << '\n';
  std::cout << "capacity: " << (int) myvector.capacity() << '\n';
  std::cout << "max_size: " << (int) myvector.max_size() << '\n';
  return 0;
}

运行结果:cplusplus官方给的一个可能结果
在这里插入图片描述

    begin

在这里插入图片描述
翻译:返回一个迭代器,该迭代器指向向量中的第一个元素。
请注意,与返回对第一个元素的引用的成员vector::front不同,此函数返回一个指向它的随机访问迭代器

    end

在这里插入图片描述
翻译:
返回一个迭代器,该迭代器引用向量容器中过去的结束元素。

过去的结束元素是向量中最后一个元素之后的理论元素。它不指向任何元素,因此不应取消引用。

由于标准库的函数所使用的范围不包括其关闭迭代器所指向的元素,因此此函数经常与vector::begin结合使用,以指定一个包含容器中所有元素的范围。

如果容器为空,此函数将返回与vector::begin相同的值。

代码验证:

// vector::begin/end
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> myvector;
    for (int i = 1; i <= 5; i++) myvector.push_back(i);

    std::cout << "myvector contains:";
    for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;
}

运行结果:
在这里插入图片描述

    front

在这里插入图片描述
翻译:
返回对vector中第一个元素的引用。
与向同一元素返回迭代器的成员vector::begin不同,此函数返回一个直接引用。
在空容器上调用此函数会导致未定义的行为。

    back

在这里插入图片描述
翻译:
返回对vector中最后一个元素的引用。
与成员vector::end不同,该函数返回的迭代器刚好经过该元素,它返回的是直接引用。
在空容器上调用此函数会导致未定义的行为。

代码验证:

// vector::front/back
#include <iostream>
#include <vector>

int main()
{
	std::vector<int> myvector;

	myvector.push_back(78);
	myvector.push_back(16);

	// now front equals 78, and back 16

	myvector.front() -= myvector.back();

	std::cout << "myvector.front() is now " << myvector.front() << '\n';

	return 0;
}

运行结果:
在这里插入图片描述

    swap

在这里插入图片描述
翻译:
用x的内容交换容器的内容,x是另一个相同类型的vector对象。尺寸可能不同

在调用该成员函数之后,该容器中的元素是调用之前在x中的元素,而x的元素是在this中的元素。所有迭代器、引用和指针对于交换的对象仍然有效。

四、iterator迭代器失效

泛型算法是针对很多容器实现的通用算法,迭代器提供一种统一的方式遍历容器的元素,让算法能够不用关心底层数据结构(因为迭代器将实现细节隐藏在了operator!=,operator++,operator*等运算符的重载函数中)。

容器的元素进行插入、删除操作后,原来的迭代器会失效
在这里插入图片描述
插入、删除操作后,两个迭代器iterator进行operator!=比较时候,经过_Compat判断,运行到上图高亮处会报错迭代器失效

解决办法:通过返回值对迭代器进行更新,如下,

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<int> myVector = {1, 2, 3, 4, 5, 6, 7, 8, 9};

	// 删除所有的奇数
	vector<int>::iterator it = myVector.begin();
	while (it != myVector.end()) {
		if (*it % 2 != 0)
		{
			// 对迭代器进行实时更新,否则容器元素改变,it迭代器会失效
			it = myVector.erase(it);
		} else {
			++it;
		}
	}
	for (int item : myVector)
	{
		cout << item << " ";
	}
	return 0;
}

运行结果:
在这里插入图片描述

当不实时更新:
在这里插入图片描述
运行报错:
在这里插入图片描述

五、小试牛刀

    题:有序vector去重

【LeetCode第二十六题】删除有序数组中的重复项

总结

vector容器底层数据结构是动态开辟的数组,每次以原来空间的2倍进行扩容
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

https://cplusplus.com/reference/vector/vector/

谢谢观看,祝顺利!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中的vector是一个动态数组,可以在运行时动态地增加或减少其大小。它提供了许多方便的方法来操作数组,例如在末尾添加元素、在任意位置插入元素、删除元素等等。下面是一些常用的vector操作: 1. 创建vector对象:可以使用默认构造函数创建一个空的vector对象,也可以使用带有初始值的构造函数创建一个包含初始值的vector对象。 ```c++ // 创建一个空的vector对象 std::vector<int> v1; // 创建一个包含初始值的vector对象 std::vector<int> v2 = {1, 2, 3}; ``` 2. 访问vector元素:可以使用下标运算符[]或at()方法来访问vector中的元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 使用下标运算符[]访问元素 int x = v[0]; // x = 1 // 使用at()方法访问元素 int y = v.at(1); // y = 2 ``` 3. 在末尾添加元素:可以使用push_back()方法在vector的末尾添加一个元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 在末尾添加一个元素 v.push_back(4); // v = {1,2, 3, 4} ``` 4. 在任意位置插入元素:可以使用insert()方法在vector的任意位置插入一个元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 在第二个位置插入一个元素 v.insert(v.begin() + 1, 4); // v = {1, 4, 2, 3} ``` 5. 删除元素:可以使用erase()方法删除vector中的一个或多个元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 删除第二个元素 v.erase(v.begin() + 1); // v = {1, 3} // 删除第二个到第三个元素 v.erase(v.begin() + 1, v.begin() + 3); // v = {1} ``` 6. 获取vector大小:可以使用size()方法获取vector中元素的数量。 ```c++ std::vector<int> v = {1, 2, 3}; // 获取vector大小 int size = v.size(); // size = 3 ``` 7. 清空vector:可以使用clear()方法清空vector中的所有元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 清空vector v.clear(); // v = {} ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值