24小时热门版块排行榜    

CyRhmU.jpeg
查看: 1417  |  回复: 19
当前只显示满足指定条件的回帖,点击这里查看本话题的所有回帖

lixy1217

木虫 (著名写手)

[交流] C++对高维数组有什么比较好的操作方式?已有2人参与

如题,所谓高维就是维数>3的情形。一般来说1维用一个指针,二维用两个指针,可维数一旦高了,例如10维的,在前面加10个 * 至少看着也不舒服吧~


而且如果要定义一个类,可以任意确定维数的,那么用加*的方式就更加没有办法应对了。当然可以换做链表的存储方式,但链表访问元素的计算耗时是不可忽略的。


另外有一个解决的方式,就是把所有的数值储存在一个数组中,再用一个长度等于维数的整数数组作为元素下标,调用元素时,只需要利用该下标的位置找到对应元素即可。可这样的话,需要消耗多少额外的计算量呢?


不知道除此之外还有什么更好的应对方式。
回复此楼

» 猜你喜欢

偶尔敞开心扉,世界将不再孤独
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

几罗星人

新虫 (初入文坛)

★ ★
小木虫: 金币+0.5, 给个红包,谢谢回帖
lixy1217: 金币+1, 谢谢参与~ 2016-02-24 12:00:45
动态高维数组可以用一位数组去模拟,就是动态分配足够大的一维数组,然后在上面模拟高维数组。就是你最后提出来的想法。
定义了数组:
        T MDA[P][Q][R][S][T]……[Y][Z]
访问MDA[a][c][d]……[j][k]即取得其指针,由于数组在内存上是连续储存的,计算指针偏移即可。计算指针偏移的算法为:
        &MDA[a][c][d]……[j][k]
          == &MDA[0][0][0][0]……[0][0] +
                (a*Q*R*S*T*……*Y*Z +
                   b    *R*S*T*……*Y*Z +
                   c        *S*T*……*Y*Z +
                   d           *T*……*Y*Z +
                   …… +
                   j                          *Z +
                   k
                )

           == &MDA[0][0][0][0]……[0][0] +
                ((((a*Q + b)*R+ c)*S+d)*T+ …… )……

而&MDA[0][0][0][0]……[0][0]正是一维数组的起始地址。下面的第二种算式从算法的角度来说可能更优一些, 少了很多乘法。不过代码不好写,而且如果我直接写下面的这种,估计看不懂规律。还是要看上面的那种。类型T是一个抽象的类型,而上式计算的指针偏移是按照类型T去算的,而不是字节,也就是中间的“+”号,每加一次,指针都是向后移动sizeof(T)个字节。

这样的模拟要增加多少运算量,如果封装成类,其他的操作都是常数时间,只有这计算地址偏移是随着维数越高而增长的。要算这个的时间复杂度的话,设维数为n,以乘法作为主要运算,则上面的是n+(n-1)+(n-2)+……+1,即O(n^2);下面的是O(n)。

上传一个我自己写的封装。类MDArray是一个高维数组,可以在构造函数中指定维数,然后变参的构造函数收取相应个数的int数值作为每一维的大小。通过MDArray.Element(下标1,下标2……)的方式访问某一个元素。只是这样有两个不好:1.改变了MDArray[][][]……的访问方式。2.必须自己保证传入的参数个数正确,否则就栈错误了。

» 本帖附件资源列表

  • 欢迎监督和反馈:小木虫仅提供交流平台,不对该内容负责。
    本内容由用户自主发布,如果其内容涉及到知识产权问题,其责任在于用户本人,如对版权有异议,请联系邮箱:xiaomuchong@tal.com
  • 附件 1 : MultiDimenArray.h
  • 2016-02-24 01:08:09, 7.43 K
17楼2016-02-24 01:16:12
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
查看全部 20 个回答

liqizuiyang

木虫 (著名写手)

★ ★ ★
小木虫: 金币+0.5, 给个红包,谢谢回帖
lixy1217: 金币+2, 没用过,Fortran 有什么相关的功能吗? 2015-09-15 08:35:46
建议改用Fortran。
2楼2015-09-14 19:22:57
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

charleslian

木虫 (小有名气)

★ ★ ★ ★
小木虫: 金币+0.5, 给个红包,谢谢回帖
lixy1217: 金币+3, 谢谢参与 2015-09-15 08:36:22
最后一个方法最好。不存在计算量的额外消耗,只是把高维数组的隐式存储变成显式的,对任意维度的数组只能这么做。只是会增加代码量,使程序不明晰。

发自小木虫IOS客户端
3楼2015-09-14 22:25:48
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

zzy滴号

金虫 (小有名气)

★ ★ ★ ★
小木虫: 金币+0.5, 给个红包,谢谢回帖
lixy1217: 金币+3, 谢谢参与 2015-09-15 08:29:38
如果不考虑效率的话,可以使用标准库中的vector来完成多维数组,其中可使用typedef来使代码更清晰。如下:
typedef std::vector<int> myVector1D ;
typedef std::vector<myVector1D> myVector2D;
typedef std::vector<myVector2D> myVector3D;
typedef std::vector<myVector3D> myVector4D;
typedef std::vector<myVector4D> myVector5D;

使用时可以如下:
myVector1D numVector1D;
numVector1D.push_back(1);
numVector1D.push_back(2);

myVector1D numVector1D2;
numVector1D2.push_back(3);
numVector1D2.push_back(4);

myVector2D numVector2D;
numVector2D.push_back(numVector1D);
numVector2D.push_back(numVector1D2);

myVector3D numVector3D;
numVector3D.push_back(numVector2D);
       
myVector4D numVector4D;
numVector4D.push_back(numVector3D);

myVector5D numVector5D;
numVector5D.push_back(numVector4D);
       
int nNum = numVector5D[0][0][0][0][0];
天道酬勤
4楼2015-09-14 23:04:02
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
普通表情 高级回复(可上传附件)
信息提示
请填处理意见