varray: 灵活的数组结构与stl valarray的解构(1)

来源:互联网 发布:淘宝数据库架构图表 编辑:程序博客网 时间:2024/06/05 23:14

valarray可以实现灵活的数组结构。我仿造valarray一步一步地实现这个类。由此我们可以看到 stl的类并不神秘。

第一步:我只实现了灵活数组类的基本功能,包括如何构造,赋值,以及简单的运算,和元素的存取。

这个数组类包含一个数据指针和数组长度。同时为了方便改变长度,另外加入了一个成员来表示改变长度。

构造方式:空数组,指定长度,指定长度并初始化为一个值,指定长度并从一个C数组初始化,从另外一个varray构造

操作:赋值,取大小,下标操作(左操作数与右操作数),求和,最大最小,左移右移等等。

其中两个用于内存管理的函数被定义为私有。


template <class T> class varray
{
T* data;
int len;
int resize_len;
private:
void clean(bool inited=0)
{
if(inited && data) delete []data;
data=0;len=0;resize_len=0;
}
void grow(int n,const T*s=0,int d=0,bool trim=0)
{
int len_0s=(data==0?0:resize_len);
if(n==0)
{
if(trim) clean(true);
}
else if(n==len_0s || n<len_0s && trim==0);
else
{
int i,m;
m=(data==0 && n<resize_len?resize_len:n);
T* np=new T[m];
int nm=(n<len?n:len);
for(i=0;i<nm;i++) np[i]=data[i];
if(s) for(;i<m;i++,s+=d) np[i]=*s;
clean(true);
data=np;
resize_len=m;
}
len=n;
}
public:
//constructor & destructors
explicit varray(int n=0) {clean();resize_len=n;grow(n);}
varray(const T& x, int n){clean();grow(n,&x);}
varray(const T* s, int n){clean();grow(n,s,1);}
varray(const varray<T>& x){clean();grow(x.size(),x.data,1);}
~varray(){clean(true);}

//some supporting function
int size() const {return len;}
void free() {clean(true);}
//element access
T operator[](int i) const {return data[i];}
T& operator[](int i) {return data[i];}

//copy & assignment
varray<T>& operator=(const varray<T>& v)
{
if(this==&v) return *this;
grow(v.size(),0,0,true);
for(int i=0;i<size();i++) data[i]=v[i];
return *this;
}
varray<T>& operator=(const T& x)
{
for(int i=0;i<size();i++) data[i]=x;
return *this;
}
void resize(int n,const T& c=T())
{
grow(n,&c,0,true);//clean & reinitialize
}


//some utils
T sum() const
{
T sum0=data[0];
for(int i=0;++i<size();) sum0+=data[i];
return sum0;
}


T min() const
{
T min0=data[0];
for(int i=0;++i<size();)
{
if(data[i]<min0) min0=data[i];
}
return min0;
}


T max() const
{
T max0=data[0];
for(int i=0;++i<size();)
{
if(data[i]>max0) max0=data[i];
}
return max0;
}

varray<T> shift(int n) const
{
static T def;
varray<T> tmp(size());
for(int i=0;i<tmp.size();i++)
{
tmp[i]=(n>0 && size()-i<=n || n<0 && i<-n ? def: data[i+n]);
}
return tmp;
}

varray<T> cshift(int n) const
{
if(size()==0);
else if(n<0)
{
if((n+=size())<0)
n=size()-(-n)%size();
}
else if(size()<=n)
n%=size();
varray<T> tmp(size());
for(int i=0;i<tmp.size();i++)
{
tmp[i]=(size()-i<=n? data[i-size()+n]:data[i+n]);
}
return tmp;
}


varray<T> apply(T fun(T)) const
{
varray<T> tmp(size());
for(int i=0;i<tmp.size();i++)
{
tmp[i]=fun(data[i]);
}
return tmp;
}


varray<T> apply(T fun(const T&)) const
{
varray<T> tmp(size());
for(int i=0;i<tmp.size();i++)
{
tmp[i]=fun(data[i]);
}
return tmp;
}
};

我们可以看一看如何使用这样一个简单的数组结构:

#include "varray.h"
#include <iostream>
#include "math.h"
using namespace std;


template <class T> T fun(const T& x)
{
return x*x+2*x+1;
}


template <class T> void disp(varray<T>& v)
{
for(int i=0;i<v.size();i++) cout<<v[i]<<'\t';
cout<<endl;
}


void main()
{
varray<double> v(10),w(1,10);
for(int i=0;i<v.size();i++) v[i]=i+1;
cout<<"v=";
disp(v);
cout<<"w=";
disp(w);
cout<<"sum(v):"<<v.sum()<<endl;
cout<<"sum(w):"<<w.sum()<<endl;
cout<<"max(v)="<<v.max()<<endl;
cout<<"min(v)="<<v.min()<<endl;


varray<double> v2=v.apply(sin);
cout<<"function:"<<endl;
disp(v2);
varray<double> v3=v.shift(2);
cout<<"shift 2:"<<endl;
disp(v3);
v3=v.shift(-2);
cout<<"shift -2:"<<endl;
disp(v3);

v3=v.cshift(2);
cout<<"cshift 2:\n";
disp(v3);
v3=v.cshift(-2);
cout<<"cshift -2:\n";
disp(v3);
}

原创粉丝点击