题目求解:把以行为主序的数存放到对应以列为主序的数组中
设有一个n×n的上三角矩阵A的上三角元素已按行为主序连续存放在数组b中,请设计一个算法trans将b中元素按列为主序连续存放在数组c中。当n=5,矩阵A 如下图所示:
其中,b=(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),c= (1,2,6,3,7,10,4,8,11,13,5,9,12,14,15)。那如何根据数组b得到c呢?
解:分析:本题主要考察特殊矩阵的压缩存储中对数组下标的灵活使用程度。用i和j分别表示矩阵中元素的行列下标,用k表示压缩矩阵b元素的下标。本题最重要是找出以行为主序和以列为主序数组下标的对应关系(初始时i=0,j=0,k=0),即:
c[j*(j+1)/2+i]=b[k];
其中,j*(j+1)/2+i就是根据等差数列得出的。根据这个对应关系,直接把b中的元素赋给c中对应的位置即可。但是读出c中一列即b中的一行(元素1,2,3,4,5)之后,还要改变行下标i和列下标,开始读6,7,8元素时,列下标j需要从1开始,行下标也需要增加1,依次类推,可以得出以下修改行下标和列下标的办法:
根据以上分析,相应的压缩矩阵转换算法如下:
void trans(int b[],int c[],int n)
//将b中元素按列为主序连续存放到数组c中
{
int step=n,count=0,i=0,j=0,k;
for(k=0;k<n*(n+1)/2;k++){
count++; //记录一行是否读完
//把以行为主序的数存放到对应以列为序的数组中
c[j*(j+1)/2+i]=b[k];
if(count==step){ //一行读完后
step--;
count=0; //下一行重新开始计数
i++; //下一行的开始行
j=n-step; //一行读完后,下一轮的开始列
}else
j++; //一行还没有读完,继续下一列的数
}
}