C++中实现动态多维数组模板的分析-06 - 悲催的科学匠人 - 冷水's blog
C++中实现动态多维数组模板的分析-06
冷水
posted @ 2010年12月31日 05:51
in C++
, 1541 阅读
这里先给出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; }