立邦涂料检测报告:关于C++多维数据标号映射

来源:百度文库 编辑:神马品牌网 时间:2024/03/29 13:47:53
关于多维数据标号映射的讨论
欢迎大家讨论,也可以当作ACM题目来做...

在C及C++中.
我很少用高维数组及高次数指针(指针的指针的指针的.......).
原因很简单.本人很笨,很难理解高维数组及高维指针,对高维数组生成操作困难且容易出错
.
所以在程序中,我一般都用一维数组及一次指针表示所有的多维数组数据.
这样分配空间简单,释放空间也简单,不用你用循环去分配和释放.
(我好象从哪里看到,CB不建议用户手动释放空间,它有完善的内存管理功能.是不是那样?)
(这种方法有一种致命局限;就是数据总数受限于unsigned long int型.多于这个数据总数只能用高次指针了.当然也可以灵活运行链表的相关知识进行扩展.)
(
//new
{
p=new double*[order];
for(int i=0;i<order;i++)
p[i]=new double[order];
}

//delete
{
for(int i=0;i<order;i++)
delete[]p[i];
delete[]p;
}
)

//-------------
数据存储就是按标准的C语言行主排列方式(不知翻译正确没有:C-standard row-major
order);
比如我用一次指针表示的二维数据:
(在工程计算中大数据都放在堆中,很少放在栈中);
int M=10;
int N=9;
double *Data=new doube[N*M] ;
//固定最高维的三维数组(可用于表示虚数):
double (*DataC)[2]=new double[N*M][2];
//同理三维,四维也可以定义:new double[M*N*L];.....

定义完了.那么我们怎么引用它们呢.
怎么用一般数组的i,j,k,w...等标号来引用Data或DataC中对应的数据呢!
这是对应关系.一种一一对应的简单的、很简单的映射关系,但是也容易出错。
如果我们是在栈中建数组:double data[10][9];
那么用data[i][j];就能正确操作数据。
但是前面定义的确良Data及DataC如何操作呢?

对Data

Data[i*N+j];*(Data+i*N+j)
对DataC

DataC[i*N+j][0],DataC[i*N+j][1];
*(*(Data+i*ny+j)+0),*(*(Data+i*ny+j)+1);

同理对于我们定义的三维复数数据:
double *DataC=new double[M*N*L][2]
数据操作:
DataC[(i*N+j)*L+k][0];
DataC[(i*N+j)*L+k][1];
*(*(DataC+(i*N+j)*L+k)+0);
*(*(DataC+(i*N+j)*L+k)+1);

从上述归纳:
对于多维连续存放在堆的数据DataC
其操作是逐步分解的过程:

操作标号:
一维:
i
二维:
(i*N)+j
三维:
((i*N)+j)*L+k
四维:
(((i*N)+j)*L+k)*W+w
依此,如此下去。
......
......
......
......

那么对于任意多维数据呢,
假设已知变量:
维数:int rank;
各维数据数:int n[rank]; // 当然对于任意维这里也应该在堆中分配,不能这样定义.
要引用的数据的标号:int Inde[rank]; //同上.
已经分配的堆数据空间:double Data=new double[n[0]*n[1]*n[2]*....*n[rank-1]];
//这里不是可用定义,只是表意而已,真正定义时请改个算法,这就是可讨论的地方。
/*
Total=1;
for(i=0;i<rank;i++)
{
Total=Total*n[i];
}
double Data=new double[Total];
*/

那么要操作标号为Inde[rank]的数据操作,如何编程呢,这里由大家发表你的看法。

用循环?
用嵌套函数?
还是.....
你有怎么办法?说说。
要求程序具的可读性,效率高,用的临时变量少。
就当作ACM题目吧!

--
#---------------------------------YiLing--------------------------------------