Vector 首先是个向量,与数组有着很紧密的联系,基本的用法都是可以用 vector 来实现的 ,但是也有很多的数组不能实现的功能。他是个不定长数组,就是长度可以不用定,可以自动延伸,比数组更加灵活简便。
下面看看用法:
1.头文件
#include<vector>
using namespace std;
vector<int>s;
也可以用 #include<bits/stdc++.h> 来表示。
2.定义向量
即可以定义单纯的一个向量 vector ,也可以定义 固定能够长度的,也可以定义一个 固定数量和元素值(相当与初始化)。
vector<int>s; // 单纯向量
vector<int>s(10) //定义数量为10的向量
vector<int>s(10,5) //是定义 一个 5个数量全是 10 的
其他的操作都基本上是一样的。
3.输入数据
1.有后插法和后压法
后压法
s.push_back(100); //后插法 插入元素
s.push_back(25);
s.push_back(999);
后插法:这里就需要用到迭代器,在这里可以往任何地方(只要不超出范围)插入数据:
s.insert(s.begin(),10000); // 插入法 需要用到 迭代器
s.insert(s.end(),1200); // 是 插到哪个位置上,数组的下标 ,end()时就是在最后
s.insert(s.begin()+2,500); //就是插入到vector 下标是 2 位置
4.数据输出
1.在这里可以用数组形式的下标输出,这里的结束条件就是s.size(),也可以用常规的迭代器输出:
for(int i=0;i<s.size();i++)
cout<<s[i]<<endl;
for(auto iter=s.begin();iter!=s.end();iter++) //迭代输出
cout<<*iter<<endl;
也可以反向迭代输出:
for(auto it1=v1.rbegin();it1!=v1.rend();it1++) //反向遍历输出
cout<<*it1<<' ';
4.常用的函数:reverse
reverse 是反转数据的一个函数,也可以用到vector 当中
reverse(v.begin(),v.end());
这就把当中的元素反转了一遍.
5.删除元素
vector 可以选择删除一个元素,也可以选择删除一段区间里的全部元素,数组则就不行。
s.erase(s.begin()+1); //删除的是 下标是1的
s.erase(s.begin(),s.begin()+4); //删除的是下标是 0到4 区间里的元素
s.erase(s.begin(),s.end()) //就是全部删除
对于元素的处理更加灵活。
6.自定义排序(借助sort)
vector 与数组有着很多相似,也可以用 sort 来排序,基本功能与数组相似(自定义排序)。比数组更加灵活,可以排各种数据。
#include<bits/stdc++.h>
using namespace std;
#include<vector>
bool cmp(string a,string b)
{
return a>b;
}
int main()
{
vector<string>s;
s.push_back("china");
s.push_back("japan");
s.push_back("App");
sort(s.begin(),s.end(),cmp);
for(int i=0;i<s.size();i++)
cout<<s[i]<<endl;
return 0;
}
sort(s.begin(),s.end(),greater<int>() ); //从大到小
sort(s.begin(),s.end(),less<int>() ) //从小到大 括号不能少
sort(s.begin(),s.end(),cmp) 自定义函数也行
一维 vector 的 形式
#include<bits/stdc++.h>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
vector<int>s;
int main()
{
s.push_back(100); //后插法 插入元素
s.push_back(25);
s.push_back(999);
//int sum=accumulate(s.begin(),s.end(),0); 计算 vector 里面元素的和
//cout<<sum<<endl;
s.insert(s.begin(),10000); // 插入法 需要用到 迭代器
s.insert(s.end(),1200); // 是 插到哪个位置上,数组的下标 ,end()时就是在最后
for(int i=0;i<s.size();i++) // 下标法输出
cout<<s[i]<<endl;
cout<<endl;
for(auto iter=s.begin();iter!=s.end();iter++) //迭代输出
cout<<*iter<<endl;
cout<<endl;
// 10000 100 25 999 1200
s.erase(s.begin()+1); //删除的是 下标是1的 也就是 100 这个元素
for(int i=0;i<s.size();i++)
cout<<s[i]<<endl;
cout<<endl;
// 10000 25 999 1200
s.erase(s.begin(),s.begin()+4 /*s.end()*/ ); //也是删除到 下标是那个数 for(int i=0;i<s.size();i++) cout<<s[i]<<endl;
cout<<endl;
s.push_back(1);
s.push_back(2);
s.push_back(3);
// 1 2 3
reverse(s.begin(),s.end()); //将 vector 元素反向排列 reverse 函数
for(int i=0;i<s.size();i++)
cout<<s[i]<<endl;
cout<<endl;
sort(s.begin(),s.end()); //不仅可以对数组,也可对 vector
for(int i=0;i<s.size();i++)
cout<<s[i]<<endl;
cout<<endl;
//sort(s.begin(),s.end(),greater<int>() ); //从大到小
//sort(s.begin(),s.end(),less<int>() ) //从小到大 括号不能少
//sort(s.begin(),s.end(),cmp) 自定义函数也行
//reverse 函数就可以来判断是否是回文串,回文数的话可以先变成字符串或字符数组
/* sort +vector 结构提供了一种 数组+sort 的加强版,不仅仅是数组,可以说,是任何数据类型,vector<xx> 这个xx 可以是string char int double 都行
不用拘束于 整形的数组 sort, 提供了一种思路吧 。再加上 cmp 自定义函数 完美 */
vector<int>v1(3); //开一个 数量为 3 的 vector
v1[0]=100;
v1[1]=20;
v1[2]=999;
for(int i=0;i<v1.size();i++)
cout<<v1[i]<<' ';
cout<<endl;
vector<int>v(10,5); //10个元素都为 5 向量
for(int i=0;i<v.size();i++)
cout<<v[i]<<' ';
cout<<endl;
for(auto it1=v1.rbegin();it1!=v1.rend();it1++) //反向遍历输出
cout<<*it1<<' ';
cout<<endl;
reverse(v1.begin(),v1.end()); //利用reverse 函数反向
for(int i=0;i<v1.size();i++)
cout<<v1[i]<<' ';
cout<<endl;
return 0;
}
来看看 更灵活的东西 resize 调整容器的长度大小 ,resize(n) 重新调整为n 个数量的容器。在不够时,可以扩充空间,再多余时,可以删除多余的空间。
在初始化时,先 resize 指定数量,就可以想 数组那样的直接输入(值初始化),不用再后插法了。
代码:
vector<int>s;
s.resize(3);
for(int i=0;i<s.size();i++){
cin>>s[i];
}
for(int i=0;i<s.size();i++)
cout<<s[i]<<' ';
对于 reserve 也是 预分配空间的,用的不多。
接下来 看看 二维的形式,与二维数组差不多:有两种形式
1.vector<vector<int>>s(maxn) maxn 是行的数量,对 列的数量定义时,就可以用 rsize 来调整数量,每个行都可以有一个 不同数量 的 列,很灵活的 达到不同需求,具体看题。
代码:
//vector<vector<int>>s(maxn) 二维vector 形式 maxn是行
vector<vector<int>>s(4); //需要写出 一维数量
//s[1].resize(a) 来调整 行数
//for(int i=0;i<4;i++)
// s[i].resize(4);
//s[0].resize(a1);
//s[1].resize(a2);
//s[2].resize(a3);
//s[3].resize(a4); a1,a2,a3,a4 的数量具体题目 而定
for(int i=0;i<s[1].size();i++)
for(int j=0;j<s[i].size();j++)
{
cin>>s[i][j];
}
for(int i=0;i<s[1].size();i++)
{
for(int j=0;j<s[i].size();j++)
cout<<s[i][j]<<' ';
cout<<endl;
}
2.vector<int>s[maxn] 形式二维 vector maxn也是行 ,跟上面的 基本是一样的
vector<int>s[3]; //s[1].resize(a) 来调整行数
//for(i=0;i<3;i++)
// s[i].resize(3); //预先开辟数量
//s[0].resize(2);
//s[1].resize(3);
//s[2].resize(1);
for(i=0;i<s[1].size();i++)
for(j=0;j<s[i].size();j++)
{
cin>>s[i][j]; //不用再 后插
}
for(i=0;i<s[1].size();i++)
{
for(j=0;j<s[i].size();j++)
{
cout<<s[i][j]<<' ';
}
cout<<endl;
}
上面两个 二维形式 也可以改变行数 .
vector 容器也可以直接find 操作,看代码实现:
vector<int>mp;
vector<int>::iterator iter=mp.begin();
mp.push_back(100);
iter=find(mp.begin(),mp.end(),100);
vector<int>s;
s.push_back(12);
s.push_back(11);
vector<int>::iterator it;
int pos=find(s.begin(),s.end(),1)-s.begin();
if(pos>=s.size()) //没有找到,这个pos就是size ,这个可以判断
cout<<"no"<<endl;
else
cout<<"yes"<<endl;
it=find(s.begin(),s.end(),1);
if(it==s.end()) //或者用迭代器来判断是否知道end()处
cout<<"no"<<endl;
else
cout<<"yes"<<endl;
这个find 操作如果找不到的话,这个迭代器就会指到end( ) 处 。
还有 二分查找函数lower_bound 和upper_bound 函数 也都是可以用的,
int pos=upper_bound(s.begin(),s.end(),12)-s.begin();
cout<<pos<<endl;
int pos=loert_bound(s.begin(),s.end(),12)-s.begin();
// 如果没有找到,还是 pos到s的size() 处
还有一些 将两个 vector 其中一个vector 中数据插入到另一个当中的操作:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
vector<int>s;
vector<int>s2;
s.push_back(12);
s.push_back(11);
s.push_back(1);
s2.push_back(100);
s2.push_back(200);
s2.push_back(300);
s2.insert(s2.end(),s.begin(),s.end());
for(int i=0;i<s2.size();i++)
cout<<s2[i]<<' ';
return 0;
}
还有一些其他的操作,就是将map中<key,value> 数据插入到 vector<pair<int,int> >中,然后用sort 排序,可以对map 进行对value 排序,这个操作很好用
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> p;
bool cmp(p a,p b)
{
return a.second>b.second;
}
int main()
{
map<int,int>mp;
mp[10]=200;
mp[200]=10;
mp[15]=555;
vector<p>s(mp.begin(),mp.end());
sort(s.begin(),s.end(),cmp);
for(int i=0;i<s.size();i++)
cout<<s[i].first<<' '<<s[i].second<<endl;
return 0;
}