分享

再议动态二维数组,通过一句表达式完成矩阵的转置

 心不留意外尘 2016-05-18

http://blog.csdn.net/silyvin/article/details/7232508

2012

先来回顾一下通常动态二维数组的创建过程,这里以 m×n int数组为例

  1. int **pp=new int*[m];  
  2. for(int i=0;i<m;++i)  
  3.     *(pp+i)=new int[n];  
  4.   
  5. //通过*(*(pp+i)+j)操作数组元素(i,j)  
  6.   
  7. for(i=0;i<m;++i)  
  8.     delete [] *(pp+i);  
  9. delete [] pp;  

这样的方式称为离散动态数组,主要存在两个缺点:

1. 数组储存区不连续;

2. 堆上空间释放比较麻烦。

图中以m=4,n=3为例。


所以我们寻求更好的代码:

  1. int *p=new int[m*n];  
  2. int **pp=new int*[m];  
  3. for(int i=0;i<m;++i)  
  4.     *(pp+i)=p+i*n;  
  5.   
  6. delete [] pp;  
  7. delete [] p;  

同样通过 *(*(pp+i)+j) 访问数组成员(i,j),先申请一段连续的空间,然后让指针数组保存它们的地址。

图中,m=4,n=3,这样做有两个好处:

1. 空间的释放更方便了;

2. 可以重新操作这段空间组成新数组。相较于第一种方式,其额外的开销仅是一个int*变量。


比如要把m×n个int所组成的空间段重分配为k×j的数组:

  1. delete [] pp;  
  2. pp=new int*[k];  
  3. for(int i=0;i<k;++i)  
  4.     *(pp+i)=p+i*j;  

图中,以k=2,j=6为例。


通过观察代码,不难发现对于任意的i,都有

  1. *(pp+i)=p+i*n;  

那么此时对于二维数组的操作事实上不需要二级指针的参与,只需一句表达式即可以用元素(i,j):

  1. int *p=new int[m*n];  
  2.   
  3. //*(p+i*n+j)——(i,j)  
  4.   
  5. delete [] p;  

其实矩阵这个概念本来就是抽象的,把一个串拆分下并列着放就是矩阵了。对于这样的存储方式,可以很轻松的完成其转置,只要换一种引用方式:

                 *(p+i+j*n)

即可完成矩阵的“转置”操作。事实上根本没有矩阵,存在的只是在内存中的一块连续空间而已,不同的访问方式显示了这块内存段在我们大脑中不同的映射。

这里并不是按常规的思维方式,先形成一个二维数组,如A(m,n),然后填充,而是创建一个串,按某种规则写入数据,按某种规则读取数据。对于普通的矩阵操作,其读写规则为同一种。

而对于一个矩阵转置问题,其本质是,按某种规则写入数据,按另一种规则读取数据,而这两种规则的不同点反映出矩阵转置的概念。内存段没变,变的是它在我们大脑中映射的矩阵,或者更准确的说是映射的规则变了。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多