向量vector
向量的使用
迭代器(iterator) 是一种允许检查容器内元素,并实现元素遍历的数据类型。迭代器提供了比下标操作更一般化的方法:所有的标准库容器都定义了相应的迭代器类型,只有少数容器支持下标操作。因为迭代器对所有的容器都适用,现代C++程序更倾向于使用迭代器而不是下标操作访问容器元素
向量vector是C++标准模板库中的内容。vector是一个容器,它能够存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,可以动态改变大小
使用向量,需要在程序中添加< vector >头文件
向量类成员函数原型如下:
//----迭代器iterators----
iterator begin(); //返回向量第1个元素为迭代器起始
iterator end(); //返回向量末尾元素为迭代器结束
reverse_iterator rbegin(); //返回向量末尾元素为逆向迭代器起始
reverse_iterator rend(); //返回向量第1个元素为逆向迭代器结束
//----容器capacity----
size_type size(); //返回向量元素数目
size_type max_size(); //返回向量能容纳的最大元素数目(长度)
void resize(size_type sz,T,c=T()); //重置向量长度为sz,c填充到扩容元素中
size_type capacity(); //返回向量容器存储空间大小
bool empty(); //测试向量是否为空
void reserve(size_type n); //为向量申请能容纳n个元素的空间
//----元素存取element access----
operator[](size_type n); //返回向量第n个位置元素的运算符,n从0起
at(size_type n); //返回向量第n个位置元素,n从0起
front(); //返回向量第1个元素
back(); //返回向量末尾元素
//----向量调节器modifiers----
void assign(size_type n,const T& u); //向量赋n个u值
void push_back(const T& x); //增加一个元素到向量末尾
void pop_back(); //删除向量末尾元素
void insert(iterator pos,size_type n,const T& x); //在向量pos处插入n个元素值x,pos从1起
iterator erase(iterator pos); //删除向量指定位置的元素,pos从1起
void swap(vector<T,Allocator>& vec); //与向量vec互换元素
void clear(); //清空向量
例:向量应用举例
#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<vector> //使用向量
using namespace std; //向量定义在std命名空间
int main()
{
//向量示例
vector<int> V1,V2; //定义向量
int A[]={1949,10,1},i;
vector<int>::iterator It;
V1.assign(A,A+3); //V1:1949 10 1
V2.assign(3,10); //V2: 10 10 10
for(i=1;i<=5;i++)
V1.push_back(i);
//V1: 1949 10 1 1 2 3 4 5
V1.pop_back(); //V1: 1949 10 1 1 2 3 4
V1.front() -= V1.back(); //V1: 1945 10 1 1 2 3 4
for(It=V1.begin();It<V1.end();It++)
V2.push_back(*It);
//遍历V1向量
//V2:10 10 10 1945 10 1 1 2 3 4
V2.insert(V2.begin(),2,300);
//V2: 300 300 10 10 10 1945 10 1 1 2 3 4
V2.erase(V2.begin()+5);
//V2: 300 300 10 10 10 10 1 1 2 3 4
for(i=0;i<V2.size();i++)
cout<<V2[i]<<" ";
//输出V2向量元素
return 0;
}
向量的实现细节
向量(vector)类似数组,但向量是动态的,即它的元素个数可以随时动态改变。例如:
vector<int> MyVec(100); //定义长度为100的向量
MyVec[50] = 1024; //给向量的某个元素赋值
int i = 0;
for( ;i<25;i++)
MyVec.push_back(1);
MyVec.resize(400); //重新定义向量的长度
例:自定义一个动态数组类模板
#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<vector>
using namespace std;
enum ErrorType {
invalidArraySize,memoryAllocationError,indexOutOfRange
};
char *errorMsg[]={"Invalid array size","Memory allocation error","Invalid index"};
template <class T>
class Array {
private:
T *alist;
int size;
void Error(ErrorType error,int badIndex=0) const;
public:
Array(int sz=50); //构造函数
Array(const Array<T>& A); //拷贝构造函数
~Array(void); //析构函数
Array<T>& operator=(const Array<T>& rhs);
T& operator[](int);
operator T*() const;
int ListSize() const;
void Resize(int sz);
};
template <class T> //模板函数Error实现输出错误信息功能
void Array<T>::Error(ErrorType error,int badIndex) const {
cout<<errorMsg[error]; //根据错误类型输出相应的错误信息
if(error==indexOutOfRange)
cout<<badIndex;
//如果下标越界,输出错误的下标
cout<<endl;
exit(1);
}
template <class T> //构造函数
Array<T>::Array(int sz) {
if(sz<=0) //如果数组长度小于0则输出错误信息
Error(invalidArraySize);
else {
//如果数组长度大于0则生成数组
size=sz;
alist=new T[size]; //动态生成数组
if(alist==NULL) //如果分配内存不成功则输出错误信息
Error(memoryAllocationError);
}
}
template <class T> //拷贝构造函数(深拷贝)
Array<T>::Array(const Array<T>& X) {
int n=X.size;
size=n;
alist=new T[n];
if(alist==NULL)
Error(memoryAllocationError);
T *srcptr=X.alist; //X.alist是对象X的数组首地址
T *destptr=alist; //本对象数组首地址
while(n--) //逐个复制数组元素
*destptr ++= *srcptr++;
}
template <class T> //析构函数
Array<T>::~Array() {
delete [] alist;
}
template <class T> //重载"="运算符,将一个数组赋值给另一个数组
Array<T>& Array<T>::operator =(const Array<T>& rhs) {
int n=rhs.size;
if(size!=n) {
delete [] alist;
alist=new T[n];
if(alist==NULL)
Error(memoryAllocationError);
size=n;
}
//从rhs向本对象复制元素
T* destptr=alist;
T* srcptr=rhs.alist;
while(n--)
*destptr ++= *srcptr++;
return *this; //返回当前的对象
}
template <class T> //重载"[]"运算符,实现通过下标访问数组元素
T &Array<T>::operator [](int n) {
if(n<0 || n>size-1) { //检查下标是否越界
Error(indexOutOfRange,n);
}
return alist[n]; //返回下标为n的数组元素
}
template <class T> //重载类型转换
Array<T>::operator T*() const {
return alist;
}
template <class T> //取当前数组的长度
int Array<T>::ListSize() const {
return size;
}
template <class T> //修改数组的长度为sz
void Array<T>::Resize(int sz) {
if(sz<=0)
Error(invalidArraySize);
if(sz==size)
return;
T *newlist=new T[sz];
if(newlist==NULL)
Error(memoryAllocationError);
int n=(sz<=size) ? sz:size; //将sz和size中较小的一个赋给n
T *srcptr=alist; //原数组的首地址
T *destptr=newlist; //新数组的首地址
while(n--)
*destptr++=*srcptr++;
delete [] alist;
alist=newlist; size=sz; //使alist指向新数组,并更新sz
}
int main()
{
int i,*p;
Array<int> a(5);
for(i=0;i<5;i++)
cin>>a[i];
for(i=0;i<5;i++)
cout<<a[i]<<" ";
cout<<endl;
Array<int>b=a;
for(i=0;i<5;i++)
cout<<b[i]<<" ";
cout<<endl;
a.Resize(10);
for(p=a;p<a+10;p++)
cout<<*p<<" ";
return 0;
}