1 vector初识
1 动态扩展
并不是在原有的空间里面之后续接新的空间,而是找更到的空间,然后将原有的数据拷贝到新的空间,释放原有空间
vector容器的迭代器是支持随机访问的迭代器
2 功能描述和函数原型
//默认构造
vector<int> v1;for (int i = 0; i < 10; i++) {v1[i] = i;
}
- 主要问题是在
test01()
函数中,你创建了一个空的vector<int> v1
,然后试图用v1[i] = i
来赋值。这是错误的,因为v1
是空的,你不能直接用下标访问和赋值。应该使用push_back()
方法添加元素
for (int i = 0; i < 10; i++) {v1.push_back(i); // 使用push_back添加元素
}
下面我们来看看vector的构造函数的使用
#include<iostream>
#include<vector>
using namespace std;void printvt(vector<int>& v) {for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {cout << *it << " ";}cout << endl;
}void test01(){//默认构造vector<int> v1;for (int i = 0; i < 10; i++) {v1.push_back(i); // 使用push_back添加元素}printvt(v1);//通过区间方式构造vector<int>v2(v1.begin(), v1.end());printvt(v2);//通过n个element进行构造vector<int>v3(10, 100);printvt(v3);//拷贝构造vector<int>v4(v3);printvt(v4);
}int main() {test01(); // 调用测试函数return 0;
}
2 vector的赋值
三种vector的赋值方式
#include<iostream>
#include<vector>
using namespace std;void printvt(vector<int>& v) {for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {cout << *it << " ";}cout << endl;
}void test01(){//默认构造vector<int> v1;for (int i = 0; i < 10; i++) {v1.push_back(i); // 使用push_back添加元素}printvt(v1);//重载符号=,进行赋值vector<int>v2;v2 = v1;printvt(v2);//assign方法(区间)vector<int>v3;v3.assign(v2.begin(), v2.end());printvt(v3);//assign方法(n个元素)vector<int>v4;v4.assign(10, 100);printvt(v4);
}int main() {test01(); // 调用测试函数return 0;
}
3 vector的容量和大小
下面是有关于vector这个容量和大小的相关函数
下面是这个代码的演示
#include<iostream>
#include<vector>
using namespace std;void printvt(vector<int>& v) {for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {cout << *it << " ";}cout << endl;
}void test01(){//默认构造vector<int> v1;for (int i = 0; i < 10; i++) {v1.push_back(i); // 使用push_back添加元素}printvt(v1);if (v1.empty()) {cout << "v1为空" << endl;}cout << "v1的容器:" << v1.capacity() << endl;cout << "v1的大小:" << v1.size() << endl;//重新指定大小//resize默认是用0进行初始化未赋值的//也可以用resize初始化别的数字v1.resize(15, 100);printvt(v1);cout << "v1的容器:" << v1.capacity() << endl;cout << "v1的大小:" << v1.size() << endl;//这样是会减少这个元素的个数的v1.resize(5);printvt(v1);
}int main() {test01(); // 调用测试函数return 0;
}
警告代码样例
v1.resize(15);
printvt(v1);
cout << "v1的容器:" << v1.capacity() << endl;
cout << "v1的大小:" << v1.size() << endl;//这样是会减少这个元素的个数的
v1.resize(15,100);
printvt(v1);
代码中 v1.resize(15, 100);
没有按预期将新增的元素设为 100
,而是保持 0
,这是因为 resize()
的第二个参数(即填充值)仅在容器扩容时才会生效
resize(n, val)
只在扩容时填充val
,如果n <= size()
,则不会修改已有元素assign(n, val)
会直接覆盖整个 vector,强制所有元素变成val
4 插入和删除
函数原型
这里的插入和删除都是要迭代器
#include<iostream>
#include<vector>
using namespace std;void printvt(vector<int>& v) {for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {cout << *it << " ";}cout << endl;
}void test01() {//默认构造vector<int> v1;for (int i = 0; i < 10; i++) {v1.push_back(i); // 使用push_back添加元素}printvt(v1);//尾删v1.pop_back();printvt(v1);//插入 提供一个迭代器进行插入//头插法1v1.insert(v1.begin(), 100);printvt(v1);//头插法2v1.insert(v1.begin(), 2, 1000);printvt(v1);//删除//删除1v1.erase(v1.begin());printvt(v1);//删除2v1.erase(v1.begin(), v1.end());printvt(v1);}int main() {test01(); // 调用测试函数return 0;
}
梳理所用的方法
push_back() 元素放入到尾部
pop_back() 弹出尾部元素
erase() 删除元素(需要提供迭代器)
insert() 插入元素(需要提供迭代器)
clear() 清除元素
如何插入到任意位置?
- 使用
begin() + index
:如果你想在特定索引位置插入元素,可以使用v1.begin() + index
来获取该位置的迭代器 - 使用
find
或其他方式定位迭代器:如果你要根据某个条件(比如值等于某个数)来插入,可以用std::find
或其他算法找到迭代器
// 1. 在索引 2 的位置(第 3 个元素)插入 100v1.insert(v1.begin() + 2, 100);printvt(v1); // 1 2 100 3 4 5// 2. 在值为 3 的元素前面插入 200auto it = find(v1.begin(), v1.end(), 3);if (it != v1.end()) {v1.insert(it, 200);}printvt(v1); // 1 2 100 200 3 4 5
5 vector数据存储
函数的原型
上面是获取元素的方式
#include<iostream>
#include<vector>
using namespace std;void printvt(vector<int>& v) {for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {cout << *it << " ";}cout << endl;
}void test01() {//默认构造vector<int> v1;for (int i = 0; i < 10; i++) {v1.push_back(i); // 使用push_back添加元素}printvt(v1);//利用[]访问for (int i = 0; i < v1.size();i++) {cout << v1[i] << " ";}cout << endl;//利用at来进行访问for (int i = 0; i < v1.size(); i++) {cout << v1.at(i) << " ";}cout << endl;//访问头元素cout << "第一个元素为:" << v1.front() << endl;//访问尾元素cout << "最后一个元素为:" << v1.back() << endl;
}int main() {test01(); // 调用测试函数return 0;
}
front()
back()
at()
operator[]
6 vector互换容器
函数原型
我们所需要学习的是怎么使用这个和这个东西的实际用途
#include<iostream>
#include<vector>
using namespace std;void printvt(vector<int>& v) {for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {cout << *it << " ";}cout << endl;
}void test01() {vector<int> v1;for (int i = 0; i < 10; i++) {v1.push_back(i); // 使用push_back添加元素}cout << "互换前:" << endl;printvt(v1);vector<int> v2;for (int i = 10; i > 0; i--) {v2.push_back(i);}printvt(v2);//互换后cout << "互换后:" << endl;v1.swap(v2);printvt(v1);printvt(v2);
}
//实际用途:巧妙运用swap收缩内存大小void test02(){vector<int>v;for (int i = 0; i < 10000; i++) {v.push_back(i);}cout << "容量大小:" << v.capacity() << endl;cout << "容器大小:" << v.size() << endl;v.resize(3);cout << "容量大小:" << v.capacity() << endl;cout << "容器大小:" << v.size() << endl;vector<int>(v).swap(v);cout << "容量大小:" << v.capacity() << endl;cout << "容器大小:" << v.size() << endl;
}int main() {//test01(); // 调用测试函数test02();return 0;
}
我们这里要重点学习这个巧用swap来缩小内存占用
容量大小:12138
容器大小:10000
容量大小:12138
容器大小:3
容量大小:3
容器大小:3
7 预留空间
函数的原型
这个主要的作用是减少重新开辟的时间开销
预留的位置不可以进行初始化,该位置未赋值就无法访问
#include<iostream>
#include<vector>
using namespace std;void printvt(vector<int>& v) {for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {cout << *it << " ";}cout << endl;
}void test01(){vector<int>v;int num = 0;int* p = NULL;for (int i = 0; i < 10000; i++) {v.push_back(i);if (p != &v[0]) {p = &v[0];num++;}}cout << num << endl;
}int main() {test01(); // 调用测试函数return 0;
}
这个一共开辟了24次才截止,但是我们用reserve就一次
#include<iostream>
#include<vector>
using namespace std;void printvt(vector<int>& v) {for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {cout << *it << " ";}cout << endl;
}void test01(){vector<int>v;v.reserve(100000);int num = 0;int* p = NULL;for (int i = 0; i < 10000; i++) {v.push_back(i);if (p != &v[0]) {p = &v[0];num++;}}cout << num << endl;
}int main() {test01(); // 调用测试函数return 0;
}
这个一般都是知道元素的大小提前预留空间节省时间的开销