C++中实现动态多维数组模板的分析-06 - 悲催的科学匠人 - 冷水's blog

C++中实现动态多维数组模板的分析-06

冷水 posted @ 2010年12月31日 05:51 in C++ , 1504 阅读

这里先给出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;

}

 

  • 无匹配
  • 无匹配

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter
Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee