C++(STL向量)
2026/7/9 15:20:20 网站建设 项目流程

分享内容

  1. 认识STL向量
  2. 向量的基础操作

栈区和堆区的作用

栈区:

· 用于存储函数调用时的局部变量、函数参数、返回地址等。
· 栈区的内存分配和释放是自动的,遵循“后进先出”(LIFO)原则。

· 栈区的大小通常有限,如果超出限制,会导致栈溢出

(Stack Overflow)
堆区:

· 用于动态分配内存,程序员可以根据需要申请和释放内存。
· 堆区的大小通常较大,但需要手动管理内存分配和释放,否则可能导致内存泄漏(Memory Leak)。

数组的特点

用int ar[100];创建一个数组。

· 长度不可变:数组在初始化后长度就固定了。
· 空间浪费:如果数组分配的大小超过实际所需,那么多余的空间就浪费了。
· 扩容成本高:扩容数组需要将所有数据复制到新数组,开销很大。

有没有在程序运行时可以动态改变长度的数组,即动态数组?

动态数组

所谓动态数组,也就是不定长数组,数组的长度是可以根据我们的需要动态改变的。动态数组的实现也不难,但是C++的STL已经提供了现成的动态数组-vector(向量)。

STL是Standard Template Library的简称,中文名标准模板库。
STL是一些“容器”、“算法”的集合。

容器:vector(向量)、stack(栈)、queue(队列)、
函数:sort(排序函数)、unique(去重函数)、…
他们都包含在STL内

STL vector

vector 的创建

  1. 包含正确的头文件
    #include <vector>

  2. 创建vector(向量)

vector<int>v;//向量名称int是向量要储存的数据类型 这种方式创建了一个空的vector,它不包含任何元素。
vector<int>v={1,2,3};//元素的初始值列表这种方式创建了一个长度为3的vector,元素为{1,2,3}

vector 的基本操作

STL vector提供一组函数实现对向量本身的操作和访问。

函数调用方式:

vector变量.函数名

或者

vector指针->函数名

1.push_back(x):在vector的尾部添加一个元素。

2.pop_back():在vector的尾部删除一个元素。

#include<iostream>#include<vector>usingnamespacestd;intmain(){vector<int>v;此时v为空 v.pushback(1);v.pushback(2);v.popback();return0;}

3.begin():获取首元素地址。end():获取未尾元素下一个地址。

可用于指定排序函数sort的参数:

#include<iostream>#include<vector>usingnamespacestd;intmain(){vector<int>v;v.pushback(5);.sort(v.begin(),v.end());return0;}

4.insert():在vector指定位置插入元素x。

#include<iostream>#include<vector>usingnamespacestd;intmain(){vector<int>v;v.pushback(1);v.pushback(2);v.insert(v.begin()+1,10);return0;}

v.insert(v.begin()+1, 10);其中v.begin()+1//待插入的地址
10是要插入的值

5.erase():删除vector指定位置的元素。

#include<iostream>#include<vector>usingnamespacestd;intmain(){vector<int>v;v.pushback(1);v.pushback(2);v.pushback(3);v.erase(v.begin()+1);//指定待删除元素的地址return0;}

vector - 练习1

访问 vector 中的元素

vector

用下标遍历:

1、正向遍历

用v.size()获取当前动态数组内元素个数

vector<int>v={1,2,3};for(inti=0;i<v.size();i++){cout<<v[i]<<" ";}下标范围:0~v.size()-1

2、反向遍历

vector<int>v={1,2,3};for(inti=v.size()-1;i>=0;i--){cout<<v[i]<<" ";}

vector 的不同创建方式

vector v;—创建了一个空的vector,它不包含任何元素
vector v = {1, 2, 3};//元素初始值列表----创建了一个长度为3的vector,元素为 {1,2,3}
vector v(10);//初始长度----创建了一个包含10个元素(默认值是0)的vector
vector v(10, 1);//元素初始值—创建一个包含10个值为1的vector
vector v(b);—创建一个与向量b有相同值的向量v

vector - 练习2

二维vector

创建一个空的二维向量:

vector<vector<int>>v2;//v2的每个元素都是vector<int>
更常见的方式:指定初始行数
vector<vector<int>>v2(5);//()里指定初始行数,// 等同一个5行的二维数组,每行都是一个空的vector<int>for(inti=0;i<5;i++){for(intj=0;j<5;j++)v2[i]·pushback(1);//在第i行末尾添加元素}v2[1][1]=3;// 用下标访问已经存在的元素vector<int>v;v2.pushback(v);//在未尾添加新一行

vector 的应用场景

(一)数据存储
vector可以方便地存储各种类型的数据,如整数、浮点数、字符串等。
(二)动态集合操作
当需要动态地添加、删除元素时,vector是一个很好的选择。例如,在一个游戏场景中,
玩家的道具列表可以使用vector来存储,玩家获取新道具时可以使用push_back()添加,使用道具时可以使用erase()删除。
(三)算法实现
vector与STL算法(如排序、查找等)配合得很好。例如,可以使用std :: sort()对vector中的元素进行排序。

移动零

给定n个数,编写一个程序将所有0移动到数列的末尾,同时保持非零元素的相对顺序。(本题要求用vector实现)
【输入描述】第一行是一个整数n。第二行有n个整数,用空格隔开。
【输出描述】按要求移动0后的数列,数之间用空格隔开。
【输入样例】5

0 1 0 3 12

【输出样例】1 3 12 00
程序流程:
1、创建一个动态数组v;
2、依次读入n个数:
非o值加入数组,0值只计数;
3、最后在末尾添加相应数量的o;
4、遍历输出。

intmain(){vector<int>v;// 创建空数组intn;cin>>n;// 依次读入数,非0值加入数组,0只计数intcnt=0;//0的个数for(inti=0;i<n;i++){inttmp;cin>>tmp;if(tmp==0)cnt++;elsev.pushback(tmp);}// 最后加入cnt个0while(cnt--)v.pushback(0);// 遍历输出for(inti=0;i<v.size();i++)cout<<v[i]<<" ";return0;}

完整代码

#include<iostream>#include<vector>usingnamespacestd;intmain(){vector<int>v;// 创建空数组intn;cin>>n;// 依次读入数,非0值加入数组,0只计数intcnt=0;//0的个数for(inti=0;i<n;i++){inttmp;cin>>tmp;if(tmp==0)cnt++;elsev.push_back(tmp);}// 最后加入cnt个0while(cnt--)v.push_back(0);// 遍历输出for(inti=0;i<v.size();i++)cout<<v[i]<<"";return0;}

移动零(扩展)

在读入n后,也可以创建一个初始长度为n的vector。

intn;cin>>n;vector<int>v(n);//创建初始长度为n的数组

【思考】此时代码如何写?直接用下标访问数组元素

// 依次读入数,非o值加入数组,0只计数intcnt=0;//0的个数intidx=0;//数组下标for(inti=0;i<n;i++){inttmp;cin>>tmp;if(tmp==0)cnt++;elsev[idx++]=tmp;// 最后加入cnt个0while(cnt--)v[idx++]=0;

接龙游戏

有n个人,每个人有一个数字序列(长度不定)。给定一个整数x,每个人可以选择一个序列中的数与x进行接龙,要求接龙的数必须大于等于x。选择接龙数值的规则:初始从第一个数开始往后找,找到第一个大于等于x的值。下次查找从序列中这个数的后一个开始找,找到大于等于接龙最后一个数的值,或者数列结束。对于每个人,求出从x开始能接龙的最长长度。
【输入描述】第一行为1个正整数n。后面2n行。两行一组,第一行是某个人的数值个数m,第二行m个数(空格隔开)。最后一行为1个正整数x。
【输出描述】
1行n个空格隔开的数。每个数表示一个人接龙的最长长度。


长度不定的数列,适合使用vector。n个人的数列可以定义成二维 vector。

程序流程:

1、创建二维vector存储n个人的序列;
2、输入每个人的m个数存入对应的数组;

intn;cin>>n;// 二维数组存储n个人的序列//每行存储一个人的序列vector<vector<int>>seq(n);for(inti=0;i<n;i++){intm;cin>>m;for(intj=0;j<m;j++){inttmp;cin>>tmp;seq[i].push_back(tmp);}}

3、对于每个人:
①顺序枚举其序列中的每个数。当前数
大于等于x,则更新x为当前数,并增
加cnt;

②最后输出这个人的接龙长度cnt。

intx;cin>>x;// 遍历查看每个人能接龙的最长长度for(inti=0;i<n;i++){intcnt=0;// 接龙长度intcurX=x;// 接龙的最后一个值for(intj=0;j<seq[i].size();j++){if(seq[i][j]>=curX)cnt++;curX=seq[i][j];}}// 输出这个人接龙的最长长度cout<<cnt<<" ";}

完整代码

3#include<iostream>#include<vector>usingnamespacestd;intmain(){intn;cin>>n;// 二维数组存储n个人的序列// 每行存储一个人的序列vector<vector<int>>seq(n);for(inti=0;i<n;i++){intm;cin>>m;for(intj=0;j<m;j++){inttmp;cin>>tmp;seq[i].push_back(tmp);}}intx;cin>>x;// 遍历查看每个人能接龙的最长长度for(inti=0;i<n;i++){intcnt=0;//接龙长度(不包含最初的x)intcurX=x;//接龙的最后一个值for(intj=0;j<seq[i].size();j++){if(seq[i][j]>=curx){cnt++;curx=seq[i][j];}}// 输出这个人接龙的最长长度cout<<cnt<<" ";}return0;}

唯一元素排序

输入N个无序的数,请将相同的数删成只剩下一个,并将删除后的数列从大到小排序后输出。(本题请用vector实现)
【输入描述】2行,第一行整数N(小于1000),表示有N个整数;第二行,N个无序的整数。
【输出描述】排序并删除相同整数后的数列。
【输入样例】10

8 32 12 25 12 8 36 25 26 12

【输出样例】36 32 26 25 12 8
比较高效的方法一定是先排序,后去重。
程序流程:

  1. 输入n个数到保存到vector;

  2. 对vector降序排序;(使用STL sort函数)

  3. 去除重复的元素;(使用STL unique函数)

  4. 输出排序、去重后的所有值;

使用STL算法库的函数,需要包含的算法头文件:

#include

排序函数与vector

sort函数对vector进行升序排序

sort(v.begin(),v.end());

● sort函数对vector进行降序排序

boolcmp(inta,intb){//实现一个大数优先的比较函数returna>=b;}sort(v.begin(),v.end(),cmp);//比较函数作为sort的第三个参数

去重函数与vector

unique函数可以对已排序的vector进行去重:

vector<int>v;...sort(v.begin(),v.end());intcnt=unique(v.begin(),v.end())-v.begin();

● unique并不真正地从容器中删除元素,而是将重复的元素移动到容器的末尾
● unique返回的地址减去首地址得到去重后的元素个数cnt
● 再根据cnt遍历去重部分的元素

程序流程:

  1. 输入n个数到保存到vector;
  2. 对vector降序排序;
  3. 去除重复的元素;
  4. 输出排序、去重后的所有值;
boolcmp(inta,intb){returna>=b;}intmain(){vector<int>v;// 创建空数组intn;cin>>n;for(inti=0;i<n;i++){inttmp;cin>>tmp;v.push_back(tmp);}sort(v.begin(),v.end(),cmp);intcnt=unique(v.begin(),v.end())-v.begin();for(inti=0;i<cnt;i++)//这里不能用v.size(),否则会输出重复的元素cout<<v[i]<<""return0;}

完整代码

#include<iostream>#include<vector>#include<algorithm>usingnamespacestd;boolcmp(inta,intb){returna>=b;}intmain(){vector<int>v;// 创建空数组intn;cin>>n;for(inti=0;i<n;i++){inttmp;cin>>tmp;v.push_back(tmp);}// 先排序(逆序)sort(v.begin(),v.end(),cmp);// 后去重复元素,cnt保存去重后的元素个数intcnt=unique(v.begin(),v.end())-v.begin();// 遍历输出for(inti=0;i<cnt;i++){cout<<v[i]<<" ";}return0;}

【注意】遍历去重后的vector不能用v.size(),只能用计算得到的cnt(去重后的元素个数),否则会输出重复的元素。

本次课程的知识点

  1. 认识STL容器中的向量(vector)

  2. 学习向量的基本操作

  3. 学习使用sort()函数对vector进行排序

  4. 学习使用unique()函数对vector进行去重

1、下面()正确定义了int型二维vector?(D)

A, vector v;

B, vector << int>> v;

C, vector v;

D, vector<vector> v;
2、在C++中,如果a和b均为float类型的变量,那么二者如果相差足够小(比如0.000001),就可以视作相等。比如2.2345676和2.2345677就可以视作相等。
下列哪个表达式能用来正确判断“a等于b”©?

A、((b-a)< 0.000001 )

C、(abs(b-a) <= 0.000001 )

B、((b-a) <= 0.000001 )

D. (sqrt(b-a) <= 0.000001 )
【提示】abs()函数对输入参数取绝对值

用vector模拟栈

请用向量vector实现栈结构,然后进行如下栈操作:输入5个整数,将这5个整数依次进行入栈,接下来做三次出栈操作,并按照出栈顺序输出出栈
元素。以上操作完成后输出此时的栈顶元素。
【输入格式】输入5个整数,用空格隔开。(1≤整数≤1000)
【输出格式】输出2行,第1行按照出栈顺序输出出栈元素,用空格隔开。第2行输出完成出栈操作后的栈顶元素。
【输入样例】4 9 12 6 7
【输出样例】7 6 12
9

#include<iostream>#include<vector>usingnamespacestd;vector<int>stack;//用动态数组模拟栈voidpush(intx){// x入栈stack.push_back(x);}intpop(){// 出栈if(!stack.empty()){intx=stack.back();stack.pop_back();returnx;}cout<<"Stack is empty";return-1;}inttop(){// 查看栈顶元素if(!stack.empty())returnstack.back();cout<<"Stack is empty";return-1;}intmain(){intx;for(inti=1;i<=5;i++){cin>>x;push(x);}for(inti=1;i<=3;i++){cout<<pop()<<'';}cout<<endl;cout<<top()<<'';return0;}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询