【PAT笔记】C++标准模板库STL(一)——vector的用法和示例

1.vector的常见用法

vector翻译为向量,但是用“长短根据需要而自动改变的数组”更容易记忆。如果要使用vector,则需要用到头文件#include <vector>,另外还需要using namespace std; 才可以使用。

PAT中的相关题目有(代码见下方):

1039 Course List for Student (25 分)

1047 Student List for Course (25 分)

1.1 vector的定义:vector<typename> name

例如:vector<int> name   vector<double> name等

引申:由此容易联想到二维数组的定义,初学者可以把二维vector数组当做两个维都可以变长的二维数组来理解更方便。因为vector<double> name本身就是一个数组,那么vector的二维数组就变成了vector<typename> Arrayname[arraySize]。这样ArraySize[0]~ArraySize[arraySize-1]中每一个都是一个vector容器。vector二维数组使用是这样的:Arrayname[x][y]

1.2 vector容器内元素的访问

(1)下标法访问:如vector<int> vi,访问vi[index]即可(如vi[1],vi[2]),但是这样的缺点也很明显,即访问除了0~vi.size()-1以外的元素会出错,失误了vector容器的灵活性。

(2)通过迭代器访问:迭代器(iterator),其定义是vector<typename>::iterator it; 如(vector<int>::iterator it=vi.begin();),从括号里的例子可以看出,这里的vi[i]和*(vi.begin()+i)是等价的。另外值得注意的一点是,与begin()正好代表第1个(数组中标记为0),end()并不是取伪元素,而是取尾元素的下一个地址,这是不同的。

1.3 vector的函数

(1)push_back():顾名思义,push_back(x)就是在vector后面添加一个元素x,示例:

for(int i=0;i<=3;i++){
    vi.push_back(i);  //将0 1 2 3 依次插入vi的末尾,可以输出0123
}

(2)pop_back():用来删除vector的尾元素,示例:

for(int i=0;i<=3;i++){
    vi.push_back(i);  //将0 1 2 3 依次插入vi的末尾,可以输出0123
}
vi.pop_back();  //删除了3

(3)size():用来获取vector的元素,示例:

vi.size();  //获得vector容器元素的个数

(4)clear():用来清除vector中的所有元素,示例:

vi.clear();  //清除vector容器的所有元素

(5)insert():insert(it,x);就是在任意迭代器it处插入一个元素x,示例:

for(int i=0;i<=3;i++){
    vi.push_back(i);  //将0 1 2 3 依次插入vi的末尾,可以输出0123
}
vi.insert(vi.begin()+2,-1);  //0 1 -1 2 3

(6)erase():删除单个元素或者删除一个区间内的所有元素,示例:

for(int i=0;i<=3;i++){
    vi.push_back(i);  //将0 1 2 3 依次插入vi的末尾,可以输出0123
}
vi.erase(vi.begin()+2);  //删除位置在2号为的元素
vi.erase(vi.begin()+1,vi.begin()+3);//删除位置在1~2号位的所有元素

 现在附上两道PAT的代码:

A1039 需要用到的是vector的二维数组存储方式和表达方式:

#include <stdio.h>
#include <algorithm>
#include <vector>
#include <string.h>
#include <iostream>
using namespace std;

const int N=40010;  //总人数 
const int M=26*26*26*10+10;  //名字的上限 
vector<int> selectCourse[M];  //每个学生选择的课程编号 

int getID(char a[]){
	int id=0;
	for(int i=0;i<3;i++){
		id=id*26+(a[i]-'A');  //我曾在这里犯了错误,误以为id*10的,导致段错误,也就是数组溢出了 
	}
	id=id*10+(a[3]-'0');
	return id;
} 

int main(){
	char name[5];
	int m,n;
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++){
		int course,x;
		scanf("%d%d",&course,&x);
		for(int j=0;j<x;j++){
			scanf("%s",name);
			int id=getID(name);
			selectCourse[id].push_back(course);  //这里就是vector的二维数组构成现场,将此事id这个学生选的课记录在后面,selectCourse本身也是数组 
		}    //可以认为selectCourse纵向分布,course在其后面横向分布 
	}
	for(int i=0;i<n;i++){
		scanf("%s",name);
		int id=getID(name);
		sort(selectCourse[id].begin(),selectCourse[id].end());
		printf("%s %d",name,selectCourse[id].size());
		for(int j=0;j<selectCourse[id].size();j++){
			printf(" %d",selectCourse[id][j]);   //vector二维数组的输出,就是输出每个学生之后选的课 
		}
		printf("\n");
	}
	return 0;
}

A1047 也是考察vector二维数组(注意二者的不同):

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <iostream>
using namespace std;
const int N=40010;
const int M=2510;  //  我在这里也犯了溢出错误,给数组的空间不够 
char name[N][5];
vector<int> course[M];

bool cmp(int a,int b){
	return strcmp(name[a],name[b])<0;
}

int main(){
	int n,m,x,courseID;
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%s%d",name[i],&x);
		for(int j=0;j<x;j++){
			scanf("%d",&courseID);	
			course[courseID].push_back(i);  //和A1039类似,这里也是存储的vector二维数组,但是这里反过来,以课程为纵轴,学生为横轴 
		}  //都是数字,课程编号和名字位置编号 
	}
	for(int i=1;i<=m;i++){
		printf("%d %d\n",i,course[i].size());
		sort(course[i].begin(),course[i].end(),cmp);
		for(int j=0;j<course[i].size();j++){
			printf("%s\n",name[course[i][j]]);  //通过课程编号和名字位置编号,可以得出名字 
		} 
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_之桐_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值