向量(vector)
向量vector初始化对象的方式有很多种,具体以下面的一些实例为准:
vector<int> v1; //元素数量为0
vector<int> v2(10); //元素数量为10,每一个元素初始化为0
vector<int> v3(10,42); //元素数量为10,每一个元素初始化为42
vector<int> v4{10}; //元素数量为1,元素初始化为10
vector<int> v5{10,42}; //元素数量为2,元素初始化为10和42
vector<string> v6{10}; //元素数量为10,每一个都被初始化为空串
vector<string> v7{10,"hi"}; //元素数量为10,每一个字符串初始化为"hi"
由上述的代码可知当向量类型为int时,圆括号中可含两个数也可以包含一个数,其中第一个数为元素的数量,第二个数为给每一个元素所附的值(默认赋值为0),花括号时每一个数都是给向量中元素赋值。当向量的类型为string时,无论花括号还是圆括号第一个数都是元素的个数,第二个串则为给每一个元素所附的初始值。
1.1编写一段程序,用cin读入一组整数并把它们存入一个vector对象中。
对于vector对象来说,直接初始化的方式适用于三种情况:一是初始值已知且数量较少;二是初始值是另一个vector的副本;三是所有元素的初始值都一样。然而一般情况下上述情况都很难满足,所以在此就要使用push_back()函数将数据存入vector对象之中。
在此特别要注意的是DevC++这个编译器中不满足C++11的相关应用,所以如果想要使用C++11的相关操作要先在编译器中进行如下操作:
(1)先选择工具栏
(2)进入编译器选项后更改其中一处的代码如下:
更改后,代码即可使用C++11的相关操作如auto,decltype的自动分析变量类型和一些for循环简单的使用。
即上述练习的代码如下所示:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v1; //元素类型为int的vector对象
int i; //记录用户的输入值
char cont = 'y'; //与用户交互,决定是否继续输入
cout<<"请输入元素内容:\n";
while(cin>>i)
{
v1.push_back(i); //向vector对象中添加元素
cout<<"您要继续输入元素吗?"<<endl;
cin>>cont;
if(cont != 'y' && cont !='Y')
break;
cout<<"请继续输入元素内容:\n";
}
for(auto men:v1)
cout<<men<<" ";
cout<<endl;
return 0;
}
运行结果如下图所示:
1.2改写上题的程序,不过这次输入的是字符串
上述练习题的代码与第一题类似其代码如下所示:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main()
{
vector<string> string1; //元素类型为string的vector对象
string str; //记录用户的输入值
char cont = 'y'; //与用户交互,决定是否继续输入
cout<<"请输入元素内容:\n";
while(cin>>str)
{
string1.push_back(str); //向vector对象中添加元素
cout<<"您要继续输入元素吗?"<<endl;
cin>>cont;
if(cont != 'y' && cont !='Y')
break;
cout<<"请继续输入元素内容:\n";
}
for(auto s:string1)
cout<<s<<" ";
cout<<endl;
return 0;
}
运行结果如下图所示:
1.3 从cin读入一组词并把它们存入一个vector对象,然后设法把所有词都改写为大写形式。输出改变后的结果。
解决上述问题需要对vector的内容进行修改同时要遍历每一个字符串的每一个字符。
用一下结构可以对该内容进行修改:
for(auto s:string1) //遍历每一个字符串
{
for(auto &c:s) //使用c遍历字符串中每一个字符并对其进行修改
c=toupper(c); //改为大写字母形式
cout<<s<<" ";
}
必须使用字符的引用才可以对其内容进行修改。
整体的代码如下所示:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main()
{
vector<string> string1; //元素类型为string的vector对象
string str; //记录用户的输入值
char cont = 'y'; //与用户交互,决定是否继续输入
cout<<"请输入第一个词的内容:\n";
while(cin>>str)
{
string1.push_back(str); //向vector对象中添加元素
cout<<"您要继续输入内容吗?"<<endl;
cin>>cont;
if(cont != 'y' && cont !='Y')
break;
cout<<"请继续输入下一个词:\n";
}
cout<<"转换后的结果是:\n";
for(auto s:string1) //遍历每一个字符串
{
for(auto &c:s) //使用c遍历字符串中每一个字符并对其进行修改
c=toupper(c); //改为大写字母形式
cout<<s<<" ";
}
cout<<endl;
return 0;
}
运行之后的结果如下图所示:
根据以上内容我们可以更改代码让其只有开头的第一个字母变为大写:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main()
{
vector<string> string1; //元素类型为string的vector对象
string str; //记录用户的输入值
char cont = 'y'; //与用户交互,决定是否继续输入
cout<<"请输入第一个词的内容:\n";
while(cin>>str)
{
string1.push_back(str); //向vector对象中添加元素
cout<<"您要继续输入内容吗?"<<endl;
cin>>cont;
if(cont != 'y' && cont !='Y')
break;
cout<<"请继续输入下一个词:\n";
}
cout<<"转换后的结果是:\n";
for(auto s:string1) //遍历每一个字符串
{
int i=0;
for(auto &c:s) //使用c遍历字符串中每一个字符并对其进行修改
{
if(i==0)
c=toupper(c);
else
c=c;
i++;
}
cout<<s<<" ";
}
cout<<endl;
return 0;
}
更改后的运行结果如下所示:
1.4 关于程序是否合法的解释。
注意:vector对象的下标运算符只能用于访问已经存在的元素,而不能用于添加元素。
使用迭代器的时候注意迭代器只要减法没有加法,因为迭代器的加法相当于两个数据的地址相加没有什么实质性的意义,然而相减不同两个迭代器相减可以算出两个迭代器之间的距离。
1.5 读入一组整数并把它们存入一个vector对象,将每对相邻的整数和算出来并输出。
该练习的代码如下所示:(ctrl+z按回车可退出第一个循环)
#include<vector>
#include<ctime>
#include<stdlib.h>
using namespace std;
int main()
{
vector<int> vc1;
int v1;
cout<<"请输入一组数据:"<<endl;
while(cin>>v1)
{
vc1.push_back(v1);
}
cout<<"现在容器中所存储的值为:"<<endl;
for(auto x : vc1){
cout<<x<<" ";
}
cout<<endl;
if(vc1.size()==0)
cout<<"没有输入数据!"<<endl;
cout<<"相邻数的求和为:"<<endl;
for(int i=0;i<vc1.size();i=i+2)
{
cout<<vc1[i]+vc1[i+1]<<" ";
if((i+2)%10==0)
cout<<endl;
}
if(vc1.size()%2!=0)
cout<<vc1[vc1.size()-1];
return 0;
}
运行结果如下图所示:
由此可知首尾相加的操作与此类似只须更改求和的循环即可,更改后如下所示:
for(int i=0;i<vc1.size()/2;i++)
{
cout<<vc1[i]+vc1[vc1.size()-i-1]<<" ";
if((i+1)%5==0)
cout<<endl;
}
if(vc1.size()%2!=0)
cout<<vc1[vc1.size()/2]<<endl;
1.6 使用迭代器来写出首尾相加的操作。
特别注意迭代器begin和end的含义,其中begin指向容器的首元素而end指向容器的最后一个元素的下一个位置,只有熟悉上述定义才能精确推断迭代器当前所处的位置。
上述练习题的代码内容如下所示:
#include<iostream>
#include<vector>
#include<ctime>
#include<stdlib.h>
using namespace std;
int main()
{
vector<int> vc1;
int v1;
cout<<"请输入一组数据:"<<endl;
while(cin>>v1)
{
vc1.push_back(v1);
}
cout<<"现在容器中所存储的值为:"<<endl;
for(auto x : vc1){
cout<<x<<" ";
}
cout<<endl;
if(vc1.size()==0)
cout<<"没有输入数据!"<<endl;
cout<<"相邻数的求和为:"<<endl;
auto beg=vc1.begin();
auto end=vc1.end();
for(auto it=beg;it!=beg+(end-beg)/2;it++)
{
cout<<(*it+*(beg+(end-it)-1))<<" ";
if((it-beg+1)%5==0)
cout<<endl;
}
if(vc1.size()%2!=0)
cout<<*(beg+(end-beg)/2)<<endl;
return 0;
}
运行后的结果如下图所示:
求相邻两相和只须更改代码内容为:
for(auto it=vc1.begin();it!=vc1.end()-1;it=it+2)
{
cout<<*it+*(++it)<<" ";
if((it-vc1.begin()+1)%10==0)
cout<<endl;
}
if(vc1.size()%2!=0)
cout<<*(vc1.end()-1);
1.7 将0-100的成绩分为11段,然后统计各个分数段的人数。
其中解决问题的代码如下所示:
#include<iostream>
#include<vector>
#include<ctime>
#include<stdlib.h>
using namespace std;
int main()
{
vector<unsigned> v1(11);
auto it = v1.begin();
int value;
cout<<"请输入一组数据:"<<endl;
while(cin>>value)
if(value<101)
++*(it+value/10);
cout<<"您总共输入了"<<v1.size()<<"个数据"<<endl;
cout<<"各分数段的分布如下:"<<endl;
for(it=v1.begin();it!=v1.end();it++)
cout<<*it<<" ";
cout<<endl;
return 0;
}
其运行结果如下所示:
1.8 vector相对于数组来说,数组有哪些缺点
数组与vector的相似之处是都能存放相同类型的对象,且这些对象本身没有名字,需要通过其所在位置访问。
数组与vector最大的不同是,数组的大小固定不变,不能随意向数组中增加额外的元素,虽然在某些情景下运行时性能好,但是与vector相比损失了灵活性。
本篇博客就此结束,还要了解相关内容的可以进入STL专栏中查找容器那一节,介绍了vector很多具体的一些函数操作。