挑战:实现动态n维数组类

BlueSky2008 2004-04-07 10:32:36
我想实现一个动态n维数组类,主要是重载操作符[]的问题,每层应该怎么返回?
有没有高手也曾想过此类问题?欢迎大家来讨论讨论.
...全文
50 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
xstring 2004-04-07
  • 打赏
  • 举报
回复
多维数组这个东西,最多也就用到四五维,

我提供的这个是拿一维的模拟的,只写到了三维,可以依葫芦画瓢写出四维和五维的来

#include <assert.h>
#include <stdio.h>
#include <malloc.h>

// pre-declaration
template < class T, bool bInternal > class Array3;

// template class Array2
template <class T, bool bInternal=false>
class Array2 {
public:
typedef Array2<T, bInternal> _Myt;
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;

Array2(int x, int y) : a(x), b(y) {
assert (x>0 && y > 0);
data = new value_type [x*y];
}
Array2(const Array2 &x) {
bInternal = x.bInternal;
if (bInternal) {
data = x.data;
} else {
a = x.a, b = x.b;
data = new value_type [a*b];
for (int i=0;i<a*b;++i)
data [i] = x.data [i];
}
}
Array2 &operator = (const Array2 &x) {
~Array2 ();
bInternal = x.bInternal;
if (bInternal) {
data = x.data;
} else {
a = x.a, b = x.b;
data = new value_type [a * b];
for (int i=0;i<a*b;++i)
data [i] = x.data [i];
}
return *this;
}
~Array2() {
if(!bInternal)
delete [] data;
}
pointer operator [] (int i) {
assert(i>= 0 && i < a);
return data + i * b;
}
const_pointer operator [] (int i) const {
assert(i>= 0 && i < a);
return data + i * b;
}
protected:
// used in template class Array3
Array2(value_type* ptr, int x, int y) : data(ptr), a(x), b(y) {
};

pointer data;
int a, b;

friend Array3<T, true>;
friend Array3<T, false>;
};

// template class Array3
template <class T, bool bInternal=false>
class Array3 {
public:
typedef Array3<T, bInternal> _Myt;
typedef Array2<T, true> a2type;
typedef const Array2<T, true> const_a2type;
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;

Array3(int x, int y, int z) : a(x), b(y), c(z) {
assert (x > 0 && y > 0 && z > 0);
data = new value_type [x*y*z];
}
Array3(const Array3 &x) {
bInternal = x.bInternal;
if (bInternal) {
data = x.data;
} else {
a = x.a, b = x.b, c = x.c;
data = new value_type (a * b * c);
for (int i=0;i<a*b*c;++i)
data [i] = x.data [i];
}
}
Array3 &operator = (const Array3 &x) {
~Array3 ();
bInternal = x.bInternal;
if (bInternal) {
data = x.data;
} else {
a = x.a, b = x.b, c = x.c;
data = new value_type (a * b * c);
for (int i=0;i<a*b*c;++i)
data [i] = x.data [i];
}
return *this;
}
~Array3() {
if(!bInternal)
delete [] data;
}
a2type operator [] (int i) {
assert(i>= 0 && i < a);
return a2type(data + i * b * c, b, c);
}
const_a2type operator [] (int i) const {
assert(i>= 0 && i < a);
return a2type(data + i * b * c, b, c);
}
protected:
// used in template class Array4
Array3(value_type* ptr, int x, int y, int z) : data(ptr), a(x),
b(y), c(z) {
};

pointer data;
int a, b, c;
};

int main(int argc, char* argv[])
{
Array3<int> a3(4, 3, 2);
for(int i=0;i<4;i++)
{
for(int j=0;j<3;j++)
{
for(int k=0;k<2;k++)
{
printf("&a[%d][%d][%d] = %p\n", i, j, k, &a3[i][j][k]);
}
}
}
return 0;
}


freefalcon 2004-04-07
  • 打赏
  • 举报
回复
vector可以呀,下面我简单模拟了一下,提供一个思路
template<typename T>
class Array{
public:
Array(){
size = 0;
elem = 0;
}
Array(int _size){
size = _size;
elem = new T[size];
}

Array(const Array& rhs) {
size = rhs.size;
elem = new T[size];
}

~Array(){
delete [] elem;
}

int resize(int _size) {
int old_size = size;
size = _size;
delete [] elem;
elem = new T[size];
return old_size;
}

T& operator[](int index){
// assert(index>-1 && index < size);
return *(elem + index);
}

Array& operator=(const Array& rhs) {
if(*rhs != this) {
size = rhs.size;
delete [] elem;
elem = new T[size];
}

return *this;
}

private:
T* elem;
int size;
};
#include <vector>
void main()
{

Array<int> a(3);
a[0] = 0;
a[1] = 1;
a[2] = 2;

typedef Array<int> A1;
Array<A1> b(2);
b[0].resize(2);
b[0][0] = 1;
b[0][1] = 2;
b[1].resize(3);
b[1][0] = 3;
b[1][1] = 4;
b[1][2] = 5;
}

如果你要求同一个维度的不同元素的size不一样,你不得不为每个元素作初始化
如果你的需求是同一个维度的所有元素的size是固定的,只是不同维度的size不同,那么你可以将size放到模板参数里面,如下:
template<typename T, int size>
class Array;
pacman2000 2004-04-07
  • 打赏
  • 举报
回复
那不如直接用一维的内存区,把[]重载一下,做一个index的换算就好了。
BlueSky2008 2004-04-07
  • 打赏
  • 举报
回复
我就是想最后M[1][2][3]这样直接寻址用,其他特性倒不是要求很多。
BlueSky2008 2004-04-07
  • 打赏
  • 举报
回复
但是这样每个维度都要初始化一下,很不方便。
pacman2000 2004-04-07
  • 打赏
  • 举报
回复
呵呵,n是固定的好处理。 有没有想过,n是不固定的呢?
pacman2000 2004-04-07
  • 打赏
  • 举报
回复
vector< vector<int> > 里面的不是指针,所以析构自己会处理的吧。
BlueSky2008 2004-04-07
  • 打赏
  • 举报
回复
上面话算我没说,是我没理解好。
BlueSky2008 2004-04-07
  • 打赏
  • 举报
回复
vector< vector<int> >M;
M.resize(8,*new(vector<int>));

最后如何析构?
勉励前行 2004-04-07
  • 打赏
  • 举报
回复
用std::vector實現多維數組不是很好嗎。
古布 2004-04-07
  • 打赏
  • 举报
回复
经典!!!
zhouqingyuan 2004-04-07
  • 打赏
  • 举报
回复
可以用内部一维数组进行模拟的,下面写的一个可以用于任意多维的,不过有些粗糙。
class Array
{
private:
int m_Dim;//数组维数
int *m_Size;//每一维的元素个数
int *array;
public:
Array(int *size,int dim=1):m_Dim(dim)
{
int num=1;
m_Size=new int[m_Dim];
for(int i=0;i<m_Dim;i++)
{
m_Size[i]=size[i];
num*=size[i];
}
array=new int[num];
for(int j=0;j<num;j++)
{
array[j]=0;
}
}
~Array()
{
if(!m_Size)
{
delete [] m_Size;
m_Size=0;
}
if(!array)
{
delete [] array;
array=0;
}
}
int& operator()(int params[],int dim)
{
int sequence=0;
if(dim==1) sequence=params[0];
else
{
sequence=params[0];
for(int i=1;i<dim;i++)
{
sequence=sequence*m_Size[i]+params[i];
}
}
int &temp=array[sequence];
return temp;
}



};
#include "multidimarray.h"
#include <iostream.h>



void main()
{
int dim[8]={2,3,4,5,6,7,8,1};
Array a=Array(dim,8);
int params[8]={0,1,3,3,3,3,3,3};
a(params,8)=5;
cout<<a(params,8)<<endl;
}

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧