多维数组

数组这玩意,我想很难找到不支持这种数据结构类型的语言了。

但是教材上为什么还要自己实现呢?因为相对一位数组来说,多维数组还是复杂些的吧?


一开始也是觉得简单到不想实现,后来在多维数组的显示函数上,还是费了点脑筋的,用到了递归。

此外要注意一定要作参数合法性检测,否则一不小心把a.Assign(100,0,0,0)写成a.Assign(0,0,0,100)这种,就会在调试时报错,让你莫名其妙半天。


主要要记录基址、维度、各维长度,此外记录一些辅助性的计算offset时要用的数值。

不考虑什么默认参数之类的情况了。

代码如下:

/*
2014.4.22
多维数组
*/

#include <iostream>
#include <cstdarg>

using std::cout;
using std::endl;

#define MAX_DIM 8

class CMyArray
{
private:
    int *base;              //基址
    int dim;                //维度
    int bounds[MAX_DIM];    //每一维的长度

    int total_memory;       //总占用空间
    int counts[MAX_DIM];    //行主序存储时,每一维的总空间大小(越靠前的维度,此值越大),便于计算元素位置

public:
    CMyArray(int dims, ...);
    ~CMyArray();

    void Assign(int data, ...);
    void Value(int *result, ...);

    void Show(int dims, int &pos);
    
    inline int GetDims(){return dim;}
    inline int GetTotalMem(){return total_memory;}
    inline int *GetBase(){return base;}
};

CMyArray::CMyArray(int dims, ...)
{
    if ((dims > MAX_DIM) || (dims < 0))
    {
        cout<<"Invalid Param"<<endl;
        exit(0);
    }

    dim = dims;

    va_list ap;
    va_start(ap, dims);
    
    //记录各维长度,并计算总占用空间大小
    total_memory = 1;
    for(int i=0; i<dims; ++i)
    {
        bounds[i] = va_arg(ap, int);
        if (bounds[i]<0)
        {
            cout<<"Invalid Param"<<endl;
            exit(0);
        }
        total_memory *= bounds[i];
    }
    va_end(ap);

    base = new int[total_memory]();

    //计算各维空间大小
    counts[dims-1] = 1;
    for(int i=dims-2; i>=0; --i)
    {
        counts[i] = counts[i+1]*bounds[i+1];
    }
}

CMyArray::~CMyArray()
{
    delete base;
    base = NULL;
}

void CMyArray::Assign(int data, ...)
{
    //计算偏移量
    int pos = 0;

    va_list ap;
    va_start(ap, data);
    for(int i=0; i<dim; ++i)
    {
        int arg = va_arg(ap, int);
        if ((arg<0)||(arg>=bounds[i]))
        {
            cout<<"Invalid Param"<<endl;
            exit(0);
        }
        pos += arg*counts[i];
    }
    va_end(ap);

    //赋值
    *(base + pos) = data; 
}

void CMyArray::Value(int *result, ...)
{
    //计算偏移量
    int pos = 0;

    va_list ap;
    va_start(ap, result);
    for(int i=0; i<dim; ++i)
    {
        int arg = va_arg(ap, int);
        if ((arg<0)||(arg>=bounds[i]))
        {
            cout<<"Invalid Param"<<endl;
            exit(0);
        }
        pos += arg*counts[i];
    }
    va_end(ap);

    //取值
    *result = *(base + pos);
}

//最低维(0维)数据间用空格隔开,其他各维间用换行加两个空格隔开
void CMyArray::Show(int dims, int &pos)
{
    //最后一维将数据横排显示
    if (1 == dims)
    {
        //排版,根据维度深度在每行开头打印相应空格
        int j = dim-dims; 
        while (j>0)
        {
            cout<<"  ";
            j--;
        }

        for(int i=0; i<bounds[dim-dims]; ++i)
        {
            cout<<*(base+pos)<<" ";
            if (pos < (total_memory - 1))
            {
                pos++;
            }
        }
    }
    //若不是最后一维,递归处理
    else
    {
        for(int i=0; i<bounds[dim-dims]; ++i)
        {
            int j = dim-dims; 
            while (j>0)
            {
                cout<<"  ";
                j--;
            }
            
            //每次退出递归前,要恢复维度数
            int dims_tmp = dims;
        
            cout<<"dim "<<(dim-dims)<<":"<<i<<endl;
            Show(--dims, pos);
            cout<<endl;

            dims = dims_tmp;
        }
    }
}

int main()
{
    CMyArray a(3, 4, 4, 4);     //3维数列,每维长度均为4
    a.Assign(100, 0, 0, 0);     //a[0][0][0] = 100
    a.Assign(200, 1, 2, 3);     //a[1][2][3] = 200

    int result;
    a.Value(&result, 1, 2, 3);
    cout<<result<<endl;         //显示a[1][2][3]

    int pos = 0;
    a.Show(a.GetDims(), pos);   //显示多维数组全部数据
    
    //顺序赋值并显示
    for(int i=0; i<a.GetTotalMem(); ++i)
    {
        *(a.GetBase()+i) = i;
    }
    pos = 0;
    a.Show(a.GetDims(), pos);

    a.Assign(100, 4, 0, 0);     //非法参数
}

/*
运行结果:
200
dim 0:0
  dim 1:0
    100 0 0 0
  dim 1:1
    0 0 0 0
  dim 1:2
    0 0 0 0
  dim 1:3
    0 0 0 0

dim 0:1
  dim 1:0
    0 0 0 0
  dim 1:1
    0 0 0 0
  dim 1:2
    0 0 0 200
  dim 1:3
    0 0 0 0

dim 0:2
  dim 1:0
    0 0 0 0
  dim 1:1
    0 0 0 0
  dim 1:2
    0 0 0 0
  dim 1:3
    0 0 0 0

dim 0:3
  dim 1:0
    0 0 0 0
  dim 1:1
    0 0 0 0
  dim 1:2
    0 0 0 0
  dim 1:3
    0 0 0 0

dim 0:0
  dim 1:0
    0 1 2 3
  dim 1:1
    4 5 6 7
  dim 1:2
    8 9 10 11
  dim 1:3
    12 13 14 15

dim 0:1
  dim 1:0
    16 17 18 19
  dim 1:1
    20 21 22 23
  dim 1:2
    24 25 26 27
  dim 1:3
    28 29 30 31

dim 0:2
  dim 1:0
    32 33 34 35
  dim 1:1
    36 37 38 39
  dim 1:2
    40 41 42 43
  dim 1:3
    44 45 46 47

dim 0:3
  dim 1:0
    48 49 50 51
  dim 1:1
    52 53 54 55
  dim 1:2
    56 57 58 59
  dim 1:3
    60 61 62 63

Invalid Param

注意点:
1,对各函数的输入参数一定要作合法性检测
2,递归显示各维数据时,注意下次序关系。
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值