矩阵的构建策略
为保证多数据的兼容性,以及广泛性。本篇笔者使用C++模板进行书写。同时变量定义使用了“()”进行初始化操作。
首先是构造可变长数组的策略:使用堆内存,笔者未使用vector。当然vector应当更方便操作
int n, m;
cin >> n >> m;
int *a = new int[n*m];
//使用此方法进行一维可变长数组的构造
int n, m;
cin >> n >> m;
int **a = new int*[n];
//使用此方法进行二维可变长数组的构造
for (int i = 0; i < n; ++i)
a[i] = new int[m];
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
a[i][j] = 0;
//此处补充二维变长数组的数据输入操作
笔者初始策略采用了二维变长数组进行了矩阵的相关操作,十分的简单粗暴。可以说是非常的舒爽了。但是,有点大材小用。毕竟以此双指针的实现策略可以用于用于解决不同行要求数据数量不同的问题。而矩阵这种行、列都已经明确知道的问题完全可以使用一维数组进行解决。
矩阵的遍历
由于使用一维数组进行矩阵操作,第一步必然为矩阵的可视化操作。实现思路很简单定义一个flag,计数输出元素,在适当的地方进行换行操作。最后不要忘记在换行之后对此变量进行重置。
/**************************************
函数名:Print
参数类型:指针,int,int
参数说明: 指针类型:指针为指向一维数组的指针
int:传参画出了传入的数组大小(size_r * size_c)
函数功能:以正确的方式输出矩阵
特别说明:进行输出时,转置前和转置后的的矩阵需要将size_r 和 size_c 的位置对调
***************************************/
template<class T>
void Print(const T* matrix, int size_r, int size_c)
{
cout << endl << "矩阵输出为:" << endl << endl;
int flag(0);
for (int i = 0; i < size_r * size_c; i++) {
cout << matrix[i] << " ";
++flag;
if (flag == size_c) { //当 flag == size_c 时,进行换行操作
cout << endl;
flag = 0;
}
}
cout << endl << "矩阵输出完成" << endl << endl;
}
矩阵转置
在二维数组先实现异常简单,只需要一个swap函数将数组对应位置的元素进行交换即可。当使用一维数组进行此行为时却没有那么理想。原本想使用单数组进行原地转置,实际操作中发现算法有点复杂(其实是笔者太菜)故笔者的解决办法是使用返回值类型为指针的函数进行操作。在函数内再次开辟新的堆内存。将原矩阵进行转置操作。将新的数组作为返回值返还。由于 C++中指向堆的指针在释放其所指内存的内容(delete操作)之后。该指针依旧存在,只是其所指内存块不在具有意义。因此也可以给该指针赋予新的值。
/**************************************
函数名:Transpose
参数类型:指针,int,int
参数说明: 指针类型:指针为指向一维数组的指针
int:传参画出了传入的数组大小(size_r * size_c)
函数功能:以正确的方法进行矩阵转置
特别说明:无
***************************************/
template<class T>
void Print(const T* matrix, int size_r, int size_c)
{
T* new_matrix = new T[size_r * size_c]{ 0 };
int row(0), col(0);
for (; row < size_r; row++) {
for (; col < size_c; col++)
new_matrix[col * size_r + row] = matrix[row * size_c + col]; //转置
col = 0; //重置循环变量
}
delete matrix;
return new_matrix;
}
矩阵的乘法
一维数组是按行优先进行矩阵存储的
因此,矩阵同行不同列的元素,在一维数组中相差的是“列”
同列不同行的元素,在一维数组中相差的是“行”
row 表示新矩阵将几行
col 表示新矩阵将有几列
mk 表示内部相乘相加循环
new_matrix[row * size_c2 + col]
row * size_c2表示当前存储到当前新矩阵的第几行 + col 表示第几列
这种写法保证了一维数组的排列模式,并且遵循了矩阵的行列
matrix1[row * size_c1 + mk]
row * size_c1 表示 matrix1 的行元素,用以确定现在进行乘法运算的元素位于第几行
+ mk 用以更新进行乘法运算的元素所处的“列”号
两者相加便是目标元素在一维数组中的目标位置
matrix2[mk * size_c2 + col]
col 表示 matrix2 需要进行乘法运算的首个列元素
mk * size_c2 挨个遍历同列元素
最后莫要忘记初始化自定义的数组。
/**************************************
函数名:Multiply
参数类型:T* T* int int int int
参数说明:传欸两个需要相乘的矩阵,
函数功能:矩阵相乘
特别说明:size_c1 和 size_r2 这两形参可以合并
***************************************/
template<class T>
T* Multiply(T* matrix1, T* matrix2, int size_r1, int size_c1, int size_r2, int size_c2)
{
if (size_c1 != size_r2)
throw"error";
T* new_matrix = new T[size_r1 * size_c2]{ 0 };
int row(0), col(0), mk(0);
for (; row < size_r1; row++) {
for (; col < size_c2; col++) {
int temp(0);
for (; mk < size_c1; mk++)
new_matrix[row * size_c2 + col] += matrix1[row * size_c1 + mk] * matrix2[mk * size_c2 + col];
mk = 0;
}
col = 0;
}
delete matrix1;
delete matrix2;
matrix1 = nullptr;
matrix2 = nullptr;
return new_matrix;
}
笔者在函数中进行了delete操作,所以在调用时,若再次进行delete变回触发异常。
然后不是很确定颜色是否能正常显示....有点慌.....
嗯,先分享这么多!