C++中实现动态多维数组模板的分析-06 - 悲催的科学匠人 - 冷水's blog
C++中实现动态多维数组模板的分析-06
冷水
posted @ 2010年12月31日 05:51
in C++
, 1604 阅读
这里先给出arrayindex类的源代码。
#ifndef ARRAYINDEX_HPP
#define ARRAYINDEX_HPP
#include <cstring>
#ifdef debug0
#include <cstdio>
#endif
class ArrayIndex
{
public:
ArrayIndex(size_t ndim, int ranges[][2]);
~ArrayIndex(void);
size_t Getsidx(int a_midx[], int& o_stat);
void Getmidx(size_t a_sidx, int o_midx[]);
size_t Getlength(void);
size_t Getndim(void);
size_t Getdim(size_t a_n);
void Getrange(size_t a_dim, int o_range[2], int& o_stat);
public:
enum{NORMAL, WRONG_DIM, WRONG_RANGE};
private:
size_t length_;
size_t ndim_;
size_t maxdim_;
size_t *dims_;
size_t *size_;
size_t **shift_;
int **range_;
};
inline size_t ArrayIndex::Getlength(void)
{
return length_;
}
inline size_t ArrayIndex::Getndim(void)
{
return ndim_;
}
inline size_t ArrayIndex::Getdim(size_t a_n)
{
return dims_[a_n];
}
inline void ArrayIndex::Getrange(size_t a_dim, int o_range[2], int& o_stat)
{
if(a_dim>=ndim_) {o_stat = ArrayIndex::WRONG_DIM; return;}
o_range[0] = range_[a_dim][0];
o_range[1] = range_[a_dim][1];
o_stat = ArrayIndex::NORMAL;
return;
}
size_t ArrayIndex::Getsidx(int a_midx[], int& o_stat)
{
size_t sidx=a_midx[0]-range_[0][0];
for(size_t n=1;n<ndim_;n++)
{
sidx += shift_[n][ a_midx[n]-range_[n][0] ];
}
return sidx;
}
void ArrayIndex::Getmidx(size_t a_sidx, int o_midx[])
{
size_t loc = a_sidx;
for(size_t n=ndim_-1; n>0; n--)
{
for(size_t m=0;m<dims_[n];m++)
if( loc >= shift_[n][m] ) o_midx[n] = m;
loc -= shift_[n][ o_midx[n] ];
o_midx[n] += range_[n][0];
}
o_midx[0] = loc + range_[0][0];
}
ArrayIndex::ArrayIndex(size_t ndim, int ranges[][2]):
ndim_(ndim),
range_(NULL)
{
range_ = new int* [ndim_];
range_[0] = new int [ndim_ * 2];
for(size_t n=1;n<ndim_;n++) range_[n] = range_[n-1] + 2;
dims_ = new size_t[ndim_];
size_ = new size_t[ndim_];
length_ = 1;
maxdim_ = 0;
for(size_t n=0;n<ndim_;n++)
{
dims_[n] = ranges[n][1] - ranges[n][0] + 1;
range_[n][0] = ranges[n][0];
range_[n][1] = ranges[n][1];
size_[n] = length_;
length_ *= dims_[n];
if(dims_[n]>maxdim_) maxdim_ = dims_[n];
}
shift_ = new size_t* [ndim_];
shift_[0] = new size_t[maxdim_*ndim_];
for(size_t n=1;n<ndim_;n++) shift_[n] = shift_[n-1] + maxdim_;
for(size_t n=1;n<ndim_;n++)
{
shift_[n][0] = 0;
for(size_t m=1;m<dims_[n];m++)
{
shift_[n][m] = shift_[n][m-1] + size_[n];
}
}
return;
}
ArrayIndex::~ArrayIndex(void)
{
delete [] shift_[0];
delete [] shift_;
delete [] range_[0];
delete [] range_;
delete [] size_;
delete [] dims_;
}
#endif
还有一个测试代码
#include "qkarray.hpp"
int main(void)
{
int stat;
size_t ndim=5;
int range[5][2] = {{1,2},{5,7},{1,5},{9,10},{1,1}}, midx[20];
ArrayIndex index(ndim,range);
index.Getrange(4, range[0], stat);
if(ndim==5)
{
size_t count = 0;
for(size_t n=0;n<ndim;n++) {
midx[n] = 0;
index.Getrange(n,range[n],stat);
printf(" Range[%5ld] = %5ld:%5ld\n", n, range[n][0],range[n][1]);
}
printf(" Array size = %d\n",index.Getlength() );
count = 0;
for(int m=range[4][0];m<=range[4][1];m++)
for(int l=range[3][0];l<=range[3][1];l++)
for(int k=range[2][0];k<=range[2][1];k++)
for(int j=range[1][0];j<=range[1][1];j++)
for(int i=range[0][0];i<=range[0][1];i++)
{
midx[0] = i; midx[1] = j; midx[2] = k; midx[3] = l;midx[4] = m;
index.Getmidx(count, midx);
count ++;
printf("[%5ld] [%5ld] [%5ld] [%5ld] [%5ld] == %5ld \n", midx[0], midx[1], midx[2], midx[3],midx[4],
index.Getsidx(midx, stat));
}
}
return 1;
}
评论 (0)