C++ Vector用法介绍


1.使用
需添加头文件
#include<vector>
using std::vector;

2.定义和初始化vector是一个类模板,而非类型,引用不是对象,所以不存在包含引用的vector,老式的声明语句中如果vector中放置的是vector,则对象的右括号后需要添加一个空格,如vector<vector<int> >
初始化的方法:

vector<T> v1 //T类型的v1 ,v1是一个空vector执行默认初始化
vector<T> v2(v1) // v2中包含v1的副本
vector<T> v2=v1  //同上
vector<T> v4(n)  // n个重复执行值初始化的对象
vector<T> v5 {a,b,c,d}  //v5包含了初始值个数的元素,每个元素被赋予相应的值
vector<T> v6={a,b,c,d}  //同上

3.常见用法:定义一个空vector,使用时再逐个添加.
C++新标准 还提供了一种为vector对象的元素赋初值的方法,列表初始化,用花括号括起来的0个或多个初始元素值被赋给vector对象.

vector<string> articles={"a","bb","ccc"};

大多数情况下,初始化方式可以相互等价地使用,例外情况:
1.使用拷贝初始化时,(即使用=)时,只能提供一个初始值.
2.如果提供的是一个类内初始值,则只能使用拷贝初始化或使用花括号的形式初始化.
3.如果提供的是初始元素值的列表,则只能把初始值都放在花括号里进行列表初始化,而不能放在圆括号里.
创建指定数量的元素

vector<int> vec(10,-1) //10个int类型的元素 每个值为-1

值初始化
通常,可以只提供数量而略去初始值,如
vector<int> ivec(10); //10 个元素 ,每个都初始化为0
特殊限制:
1.有些类要求必须提供初始值
2.如果只提供了元素的数量,而没有设定初始值,
区别:初始化依赖于传递初始值时是花括号或圆括号,

vector<int> v1(10);   //v1有10个元素,每个值都是0
vector<int> v2{10};   //v2只有一个元素,值为10
vector<int> v3(10,1)    //v3是10个1
vector<int> v4{10,1}    //v4是10和1
//圆括号,可以说提供的是用来构造vector对象,
//花括号,可以理解为列表初始化该vector对象,
//初始化过程中,尽可能把花括号内的值当成是元素的初始值的列表来处理,只有无法执行列表初始化时才会把花括号中的值当成是元素初始值来处理
vector<string> v5{"hi"}  //列表初始化,v5有一个元素
vector<string>   v6("hi"   //不能使用字符串字面值构建vector对象
vector<string>   v7(10);   //确认无法执行列表初始化后,编译器会尝试用默认值初始化vector对象
尾部添加元素
vector<int> vec;
vec.push_back(a);
插入元素
vec.insert(vec.begin()+i,a);  //在第i+1个元素前面插入a;

注意:如果循环体内部包含有vector对象添加元素的语句,则不能使用范围for循环.
4.vector其他操作
容量大小: vector c; c.size();
清空: c.clear();
是否空: c.empty();

 vector<int> v {1,2,3,4,5,6,7,8,9};
 for(auto & i:v)
 i*=i;

vector的size函数返回值的类型由vector定义的size_type 类型.
要使用size_type,需首先指定它是由那种类型定义的,vector对象类型总是包含着元素的类型.
vector<int> ::size_type
不能用下标形式添加元素,下标运算符只能用来访问,不能添加元素,只能对确知已经存在的元素执行下标操作.
注意:通过下标访问不存在的行为非常常见,会产生严重后果.确保下标合法的一种有效手段是尽可能使用范围for语句.
5.迭代器介绍
类似于指针,迭代器提供了对对象的间接访问,迭代器有有效和无效之分.有效的迭代器或者指向一个元素,或者指向容器中尾元素的下一个元素.其他情况均属于无效.
使用迭代器
begin()指向第一个,end()指向尾元素的下一个位置,(不存在的尾后元素)
如果容器为空,则begin和end返回的是同一个迭代器,都是尾后迭代器.
end()返回的迭代器并不实际指示某个元素,所以不能对其进行递增或者解引用的操作.
所有的标准库容器都定义了一个==和!=,要养成使用!=的习惯.
迭代器运算

vector<int> ::iterator it;//it能读写vector<int>的元素
vector<int> ::const_iterator it1; //it2只能读元素,不能写元素
//后者和常量指针差不多,

如果vector对象是一个常量,则只能使用后者,不是的话,两者都可以.
如果是常量,begin和end返回的是const_iterator,如果不是常量,返回的是iterator.
为专门得到const_iterator类型的返回值,C++11新标准引入了两个新函数,cbegin()和cend;
限制
1.vector对象可以动态增长,不能在范围for循环中向vector对象添加元素
2.任何一种可能改变vector对象容量的操作.都会使该vector对象的迭代器失效.
参与比较的两个迭代器必须合法而且指向的是同一个容器的元素. 两个迭代器若相减,所得结果是两个迭代器的距离,类型是difference_type,距离可正可负,
使用迭代器的经典算法:二分搜索
二分搜索是从有序序列中寻找某个给定的值。从序列的中间位置开始搜索,部分代码如下:

//text必须是有序的
auto beg=text.begin(),end=text.end();
auto mid=text.begin()+(end-beg)/2;//初始状态下的中间点
//当还有元素尚未检查并且我们还没有找到时执行循环
while(mid!=end&&*mid!=sought)
{
if(sought<*mid)
end=mid;
else
beg=mid+1;
mid=beg+(end-begin)/2;

欢迎大家批评指正.有相关内容会继续补充.

猜你喜欢

转载自blog.csdn.net/xiongluo0628/article/details/75138690