用STL可变数组vector容器完成洛谷P3156“询问学号”

#vector#   #数据结构#  #洛谷P3156#   #询问学号#

目录

 vector容器的基本概念

vector容器的使用方法 

头文件(使用前必须加上)

vector的构造函数 

 vector的赋值操作

 vector的容器与大小

vector的插入与删除 

vector数据存取 

 vector互换容器

vector预留空间

 洛谷P3156“询问学号”的解法

     题目

用数组解

用vector解

结尾 


 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的具体用法。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值