#vector# #数据结构# #洛谷P3156# #询问学号#
目录
vector容器的基本概念
概念:与数组相似,可以把vector容器看作一个特殊的数组。
vector容器与数组的区别
1.数组的静态的,长度不可变化;vector容器是动态的,可以变化长度。
2.数组内数据通常存储在栈上,而vector中数据存储在堆上
vector容器的动态扩展:
动态扩展并不是在原空间之后续接新空间,而是找到比原来更大的内存空间,将原数据拷贝到新空间,释放原空间 。
vector容器的使用方法
-
头文件(使用前必须加上)
#include<vector>
-
vector的构造函数
1. vector<T> v; //使用模板类,默认构造函数,T为数据类型,v为自定义数据名
2. vector(v.begin(),v.end()); //将v.begin至v.end这段区间的元素拷贝给本身,一般用在打印 函数
3.vector(n , m ); //将 n 个 m 拷贝到本身
4.vector<T>v(v1); //将v中的值全部拷贝到v1中去
为了方便,我们自定义一个打印输出函数
void printVector(vector<int>& v)
{
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
测试案例:
void test()
{
//默认构造,无参构造
vector<int>v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);
//通过区间的方式进行构造
vector<int>v2(v1.begin(), v1.end());
printVector(v2);
//n个m方式构造
vector<int>v3(10, 100);
printVector(v3);
//拷贝构造
vector<int>v4(v1);
printVector(v4);
}
-
vector的赋值操作
1.vector& operator=(const vector &v); //重载赋值运算符
2.assign(v.begin(),v.end()); //将v.begin至v.end这段区间中的元素赋值给本身
3.assign(n,m); //将n个m赋值给本身
测试案例:
void test01()
{
vector<int>v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
}
printVector(v1);
//赋值 operator =
vector<int>v2;
v2 = v1;
printVector(v2);
// assign
vector<int>v3;
v3.assign(v1.begin(), v1.end()); //前闭后开!!!!
printVector(v3);
//n个m 方式赋值
vector<int>v4;
v4.assign(10, 100);
printVector(v4);
}
-
vector的容器与大小
1.empty(); //判断容器是否为空,为空返回1,否则返回0
2.capacity(); //返回容器的容量
3.size(); //返回容器的大小,即容器中元素的个数
4.resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值0填充新位置,如 //果容器变短,则末尾超过容器长度的元素被删除
5.resize(int num,int elem); //重新指定容器的长度为num,若容器变长,则以elem填充新位 // 置,如果容器变短,则末尾超过容器长度的元素被删除
测试案例:
void test02()
{
vector<int>v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
}
printVector(v1);
if (v1.empty()) //为真 代表容器为空
{
cout << "v1为空";
}
else
{
cout << "v1不为空" << endl;
cout << "v1的容量为:" << v1.capacity() << endl;
cout << "v1的大小为:" << v1.size() << endl;
}
//重新指定大小(resize)
v1.resize(15);
printVector(v1); //如果重新指定的比原来的长的,默认用0填充的位置
//重载版本
v1.resize(15, 100); //利用重载的版本,可以指定填充值,这里为100
printVector(v1);
//比原来短
v1.resize(5);
printVector(v1); //删除超出的部分
}
-
vector的插入与删除
1.push_back(ele); //尾部插入元素ele
2.pop_back(); //删除最后一个元素
3.insert(const_iterator pos,ele); //在迭代器指向的位置pos处插入一个元素ele
4.insert(const_iterator pos,int count,ele); //在迭代器指向的位置pos处插入count个元素ele
5.erase(const_iterator pos); //删除迭代器指向的元素
6.erase(const_iterator begin,const_iterator end); //删除迭代器从begin到end之间的元素
7.clear(); //删除容器中所有元素
测试案例:
void test03()
{
vector<int>v1;
//尾插
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
v1.push_back(50);
v1.push_back(60);
//遍历
printVector(v1);
//删去尾部
v1.pop_back();
printVector(v1);
//在头部加一个
v1.insert(v1.begin(), 100);
printVector(v1);
//在头部加n个
v1.insert(v1.begin(),2, 100);
printVector(v1);
//删除头部
v1.erase(v1.begin());
printVector(v1);
//清空
v1.erase(v1.begin(), v1.end());
printVector(v1);
v1.clear();
printVector(v1);
}
-
vector数据存取
1.at(int idx); //返回索引idx所指的数据
2.operator[]; //返回[]内索引所指的数据
3.front(); //返回容器中第一个元素
4.back(); //返回容器中最后一个元素
测试案例:
void test04()
{
vector<int>v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
}
//利用[]的方式来访问数组中的元素
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;
}
-
vector互换容器
swap(v); //容器v与当前容器互换
测试案例 :
void text05()
{
vector<int> v1,v2;
for (int i = 0; i < 10; ++i)
{
v1.push_back(i);
v2.push_back(9 - i);
}
//交换前
printVector(v1);
printVector(v2);
//交换后
v1.swap(v2); //调用互换函数
printVector(v1);
printVector(v2);
}
-
vector预留空间
功能:减少vector在动态扩容时的扩展次数
注意:每次使用push_back(v)时,如果容器v的大小要超过v的容量时,系统就会对v进行一 次动态扩容,至于扩大多少空间,由系统决定测试案例:
void text06()
{
vector<int> v1,v2;
v2.reserve(10000);//给v2设置预留空间,v1不设置
//对比v1,v2,系统需要动态扩容多少次
int num1 = 0; //扩容次数
int num2 = 0;
int capacity1 = 0; //容量大小
int capacity2 = 0;
for (int i = 0; i < 10000; ++i)
{
v1.push_back(i);
if (capacity1 != v1.capacity())//计算扩容次数,当容量不相等时,证明系统扩容了
{
capacity1 = v1.capacity();
++num1;
}
v2.push_back(i);
if (capacity2 != v2.capacity())
{
capacity2 = v2.capacity();
++num2;
}
}
cout << "系统对v1扩容" << num1 << "次" << endl;
cout << "系统对v2扩容" << num2 << "次" << endl;
}
洛谷P3156“询问学号”的解法
题目
有 n(n≤2×10**6) 名同学陆陆续续进入教室。我们知道每名同学的学号(在 11 到 10**9 之间),按进教室的顺序给出。上课了,老师想知道第 i 个进入教室的同学的学号是什么(最先进入教室的同学 i=1),询问次数不超过 105105 次。
输入格式
第一行 22 个整数 n 和m,表示学生个数和询问次数。
第二行 n 个整数,表示按顺序进入教室的学号。
第三行 m 个整数,表示询问第几个进入教室的同学。
输出格式
输出 m 个整数表示答案,用换行隔开。
输入输出样例
输入
10 3 1 9 2 60 8 17 11 4 5 14 1 5 9
输出 #
1 8 5
用数组解
代码:
#include<iostream>
using namespace std;
typedef long long ll;
ll n, m,arr[2000000],brr[2000000];
int main()
{
cin >> n >> m;
for (ll i = 0; i < n; i++) {
ll a;
cin >> a;
arr[i] = a;
}
for (ll i = 0; i < m; i++) {
ll b ;
cin >> b;
brr[i] = b;
}
for (ll i = 0; i < m; i++) {
cout << arr[brr[i] - 1] << endl;
}
return 0;
}
结果:
用vector解
代码:
#include<iostream>
#include<vector>
using namespace std;
typedef long long ll;
ll n, m;
int main()
{
cin >> n >> m;
vector<int>v1;
for (int i = 0; i < n; i++) {
int a;
cin >> a;
v1.push_back(a);
}
vector<int>v2;
for (int i = 0; i < m; i++) {
int b;
cin >> b;
v2.push_back(b);
}
for (int i = 0; i < m; i++) {
cout << v1[v2[i] - 1];
cout << endl;
}
return 0;
}
结果:
结尾
vector容器算是C++中最常用的容器之一了,
我才不会告诉你本蒟蒻之前用二维数组解,结果超内存才去学vector的。现在学习完了,详细总结了vector的具体用法。