题目描述:
在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。
给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。
重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。
如果具有给定参数的 reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。
题目解析:
题目中给出的函数参数为
(int** mat, int matSize, int* matColSize, int r, int c, int* returnSize, int** returnColumnSizes)
其中** mat表示原始矩阵,即二维数组
matSize为原始矩阵的行数
matColSize是一个一维数组,该数组长度为matSize,每个元素中存储的是对应行的列 数
r是重塑后的行数 c是重塑后的列 数
*returnSize获取的是变量returnSize的地址,其值为重塑后的行数。
**returnColumnSizes是一个二级指针,获取的是一维数组*returnColumnSizes的地址,该数组长度为r,每个元素中存储的是重塑后的矩阵对应行的列 数。
此题目考察的是对二维数组的运用
首先判断初始矩阵的行列乘积和 r*c 是否相同,不同返回原始矩阵,相同则给一个二维数组分配地址用来存放重构后的矩阵。
二维数组开辟方法:定义一个二级指针,在二级指针中分配 r 个一级指针类型的地址,然后对每个一级指针都分配 c 个 int 类型的地址。从而建立了行数为r,列数为 c 的二维数组.
其中 *returnColumnSizes 也要分配地址
代码如下:
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** matrixReshape(int** mat, int matSize, int* matColSize, int r, int c, int* returnSize, int** returnColumnSizes){
int ori_r = matSize; //m
int ori_c = matColSize[0]; //n
if(ori_r*ori_c != r*c)
{
*returnSize = matSize;
*returnColumnSizes = matColSize;
return mat;
}
*returnSize = r;
*returnColumnSizes = (int*)malloc(sizeof(int)*r);
int** returnMatrix = (int**)malloc(sizeof(int*)*r);
for(int i=0; i<r; i++)
{
(*returnColumnSizes)[i] = c;
*(returnMatrix+i) = (int*)malloc(sizeof(int)*c);
}
int flag1 = 0;
int flag2 = 0;
for(int i=0; i<r;++i)
{
for(int j=0; j<c; ++j)
{
if(flag2<ori_c)
{
returnMatrix[i][j] = mat[flag1][flag2];
flag2++;
}
else
{
flag1++;
flag2=0;
returnMatrix[i][j] = mat[flag1][flag2];
flag2++;
}
}
}
return returnMatrix;
}
对于如何将原始矩阵依次赋值给重塑矩阵,本人想到的方法就是定义两个变量记录原始矩阵的位置,通过不断更新变量来达到赋值的效果。而官方给的方法更厉害一点。他的思路是:
一个 m * n 的矩阵,m是行数,n是列数,第 i 个元素的行列坐标分别为(i/n, i%n)
细想一下,如果第i个元素小于n,那它就是第一行的第 i 个值;
大于n时,则 i/n 得到行的位置,列的位置就是 i/n 后的余数。
故根据此公式让两个矩阵的每个元素一一对应。即
newMatrix[i/c][i%c] = mat[i/ori_c][i%ori_c]
代码更新为如下:
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** matrixReshape(int** mat, int matSize, int* matColSize, int r, int c, int* returnSize, int** returnColumnSizes){
int ori_r = matSize; //m
int ori_c = matColSize[0]; //n
if(ori_r*ori_c != r*c)
{
*returnSize = matSize;
*returnColumnSizes = matColSize;
return mat;
}
*returnSize = r;
*returnColumnSizes = (int*)malloc(sizeof(int)*r);
int** returnMatrix = (int**)malloc(sizeof(int*)*r);
for(int i=0; i<r; i++)
{
(*returnColumnSizes)[i] = c;
*(returnMatrix+i) = (int*)malloc(sizeof(int)*c);
}
for(int i=0; i<r*c;++i)
{
returnMatrix[i/c][i%c] = mat[i/ori_c][i%ori_c];
}
return returnMatrix;
}