一、知识储备
• 矩阵与矩阵之间可以进行加法、减法和乘法运算(矩阵的“除法”,被特别地定义出了逆矩阵,通过一个矩阵与另一个的逆矩阵的乘法来实现),矩阵和数之间可以进行数乘运算;
• 矩阵的加法和减法一致,均需要满足参加运算的矩阵具有相同的行列规模,矩阵加减法运算规则如下:如果有矩阵
• 矩阵的乘法比较特殊:对于
乘法运算结果满足:
其中
• 矩阵的数乘较为简单:矩阵数乘结果满足
二、基本思路
• 为了方便输入多个矩阵并进行多次计算,我们用 struct 结构体来储存矩阵;用户则通过选择矩阵在组中的下标选出要参加运算的矩阵;
• 定义三个函数分别实现乘法、加(减)法运算和数乘运算;
• 在进行运算之前,需要根据输入矩阵的行列规模判断矩阵之间是否可做加减法或乘法;
• 为了方便调用计算结果,把运算结果也存入结构体中,下标顺延.
三、实现方法
• 在定义主函数之前,我们构建一个结构体,储存矩阵以及矩阵的行列规模:
struct matrix_group
{
float matrix[20][20];
int rows;
int columns;
} group[100];
• 定义三个函数分别进行矩阵的乘法、加(减)法和数乘运算:
void do_matrix_multiplication(void);
void do_matrix_addition(int sign);
void do_scalar_multiplication(void);
由于加法运算函数要实现加减两种运算的功能,因此我们向加法运算函数中传入符号 sign ,加法为1,减法为 -1.
• 为了实现储存计算结果并顺延下标,定义全局变量:
int numbers = 0;
每当 group 中新增一个矩阵,numbers 自增加 1;
• 为了方便用户做出选择,定义一个用于输出菜单的函数:
void menu(void)
{
printf("n");
printf("[1]矩阵乘法.n");
printf("[2]矩阵加法.n");
printf("[3]矩阵减法.n");
printf("[4]矩阵数乘.n");
printf("[9]输入矩阵.n");
printf("[0]退出.n");
printf("你的选择是:");
}
在主函数中接受用户输入的选择,并调用相应的函数输出结果;
• 定义主函数:begin 部分用于实现回溯,并输入用户指定个数的矩阵;menu 部分通过调用menu 函数向用户显示菜单,并接受用户指令进行相应的操作:
int main()
{
int n,i,j,k,choice = -1;
begin:
printf("输入的矩阵个数为:");
scanf("%d",&n);
for(k = numbers;k < numbers + n;k ++)
{
printf("矩阵 %d 的行规模和列规模是(中间以空格分隔):",k + 1);
scanf("%d %d",&group[k].rows,&group[k].columns);
for(i = 0;i < group[k].rows;i ++)
for(j = 0;j < group[k].columns;j ++)
scanf("%f",&group[k].matrix[i][j]);
}
numbers += n;
menu:
menu();
scanf("%d",&choice);
if(choice == 0)
goto end;
else if(choice == 9)
goto begin;
else
{
if(choice == 1)
do_matrix_multiplication();
else if(choice == 2)
do_matrix_addition(1);
else if(choice == 3)
do_matrix_addition(-1);
else if(choice == 4)
do_scalar_multiplication();
else
printf("指令不正确,重新输入!n");
goto menu;
}
end:
return 0;
}
• 接下来完善三个用以计算并输出结果的函数,这三个函数均需要完成“计算结果 → 输出结果 → 将结果储存为新的矩阵”这三个步骤:
· 首先是矩阵乘法运算函数. 在函数开头,需要确保矩阵可以做乘法,因此引入判断;如果判断可做乘法,利用数学关系
void do_matrix_multiplication(void)
{
int p,q,i,j,k;
printf("选择两个矩阵,输入它们的下标,中间以空格分隔:");
scanf("%d %d",&p,&q);
if(group[p - 1].columns != group[q - 1].rows)
printf("矩阵乘法不可做!n");
else
{
for(i = 0;i < group[p - 1].rows;i ++)
{
for(j = 0;j < group[q - 1].columns;j ++)
{
for(k = 0;k < group[p - 1].columns;k ++)
group[numbers].matrix[i][j] += group[p - 1].matrix[i][k] * group[q - 1].matrix[k][j];
printf("%.3ft",group[numbers].matrix[i][j]);
}
printf("n");
}
group[numbers].rows = group[p - 1].rows;
group[numbers].columns = group[q - 1].columns;
printf("运算结果已经被储存为 矩阵 %dn",++numbers);
}
}
· 接着是矩阵加法运算函数. 同样需要先判断是否可做加减;如果加减法可做,则根据主函数中传入的 sign 符号确定是做加法还是做减法;输出并储存矩阵的过程同上:
void do_matrix_addition(int sign)
{
int i,j,p,q;
printf("选择两个矩阵,输入它们的下标,中间以空格分隔:");
scanf("%d %d",&p,&q);
if((group[p - 1].rows != group[q - 1].rows) != (group[p - 1].columns != group[q - 1].columns))
printf("矩阵加减法不可做!n");
else
{
for(i = 0;i < group[p - 1].rows;i ++)
{
for(j = 0;j < group[q - 1].columns;j ++)
{
printf("%.3ft",group[p - 1].matrix[i][j] + sign * group[q - 1].matrix[i][j]);
group[numbers].matrix[i][j] = group[p - 1].matrix[i][j] + sign * group[q - 1].matrix[i][j];
}
printf("n");
}
group[numbers].rows = group[p - 1].rows;
group[numbers].columns = group[q - 1].columns;
printf("运算结果已经被储存为 矩阵 %dn",++numbers);
}
}
· 最后是矩阵数乘运算函数. 这个过程比较简单,不需要判断条件直接进行运算即可:
void do_scalar_multiplication(void)
{
int i,j,p;
float num;
printf("选择一个矩阵,输入它的下标:");
scanf("%d",&p);
printf("输入一个用以数乘的数字:");
scanf("%f",&num);
for(i = 0;i < group[p - 1].rows;i ++)
{
for(j = 0;j < group[p - 1].columns;j ++)
{
printf("%.3ft",num * group[p - 1].matrix[i][j]);
group[numbers].matrix[i][j] = num * group[p - 1].matrix[i][j];
}
printf("n");
}
group[numbers].rows = group[p - 1].rows;
group[numbers].columns = group[p - 1].columns;
printf("运算结果已经被储存为 矩阵 %dn",++numbers);
}
到此为止,此程序就能够实现矩阵的加法、减法、乘法和数乘运算,并将计算结果保留下来.
对全过程进行组合、适当简化,有以下全部过程的代码:
#include <stdio.h>
void do_matrix_multiplication(void);
void do_matrix_addition(int sign);
void do_scalar_multiplication(void);
void menu(void);
struct matrix_group
{
float matrix[20][20];
int rows;
int columns;
} group[100];
int numbers = 0;
int main()
{
int n,i,j,k,choice = -1;
begin:
printf("输入的矩阵个数为:");
scanf("%d",&n);
for(k = numbers;k < numbers + n;k ++)
{
printf("矩阵 %d 的行规模和列规模是(中间以空格分隔):",k + 1);
scanf("%d %d",&group[k].rows,&group[k].columns);
printf("请输入一个%d行%d列的矩阵:n",group[k].rows,group[k].columns);
for(i = 0;i < group[k].rows;i ++)
for(j = 0;j < group[k].columns;j ++)
scanf("%f",&group[k].matrix[i][j]);
}
numbers += n;
menu:
menu();
scanf("%d",&choice);
if(choice == 0)
goto end;
else if(choice == 9)
goto begin;
else
{
if(choice == 1)
do_matrix_multiplication();
else if(choice == 2)
do_matrix_addition(1);
else if(choice == 3)
do_matrix_addition(-1);
else if(choice == 4)
do_scalar_multiplication();
else
printf("指令不正确,重新输入!n");
goto menu;
}
end:
return 0;
}
void do_matrix_multiplication(void)
{
int p,q,i,j,k;
printf("选择两个矩阵,输入它们的下标,中间以空格分隔:");
scanf("%d %d",&p,&q);
if(group[p - 1].columns != group[q - 1].rows)
printf("矩阵乘法不可做!n");
else
{
for(i = 0;i < group[p - 1].rows;i ++)
{
for(j = 0;j < group[q - 1].columns;j ++)
{
for(k = 0;k < group[p - 1].columns;k ++)
group[numbers].matrix[i][j] += group[p - 1].matrix[i][k] * group[q - 1].matrix[k][j];
printf("%.3ft",group[numbers].matrix[i][j]);
}
printf("n");
}
group[numbers].rows = group[p - 1].rows;
group[numbers].columns = group[q - 1].columns;
printf("运算结果已经被储存为 矩阵 %dn",++numbers);
}
}
void do_matrix_addition(int sign)
{
int i,j,p,q;
printf("选择两个矩阵,输入它们的下标,中间以空格分隔:");
scanf("%d %d",&p,&q);
if((group[p - 1].rows != group[q - 1].rows) != (group[p - 1].columns != group[q - 1].columns))
printf("矩阵加减法不可做!n");
else
{
for(i = 0;i < group[p - 1].rows;i ++)
{
for(j = 0;j < group[q - 1].columns;j ++)
{
printf("%.3ft",group[p - 1].matrix[i][j] + sign * group[q - 1].matrix[i][j]);
group[numbers].matrix[i][j] = group[p - 1].matrix[i][j] + sign * group[q - 1].matrix[i][j];
}
printf("n");
}
group[numbers].rows = group[p - 1].rows;
group[numbers].columns = group[q - 1].columns;
printf("运算结果已经被储存为 矩阵 %dn",++numbers);
}
}
void do_scalar_multiplication(void)
{
int i,j,p;
float num;
printf("选择一个矩阵,输入它的下标:");
scanf("%d",&p);
printf("输入一个用以数乘的数字:");
scanf("%f",&num);
for(i = 0;i < group[p - 1].rows;i ++)
{
for(j = 0;j < group[p - 1].columns;j ++)
{
printf("%.3ft",num * group[p - 1].matrix[i][j]);
group[numbers].matrix[i][j] = num * group[p - 1].matrix[i][j];
}
printf("n");
}
group[numbers].rows = group[p - 1].rows;
group[numbers].columns = group[p - 1].columns;
printf("运算结果已经被储存为 矩阵 %dn",++numbers);
}
void menu(void)
{
printf("n");
printf("[1]矩阵乘法.n");
printf("[2]矩阵加法.n");
printf("[3]矩阵减法.n");
printf("[4]矩阵数乘.n");
printf("[9]输入矩阵.n");
printf("[0]退出.n");
printf("你的选择是:");
}
大功告成!
我们以二阶方阵
以上实现方法并非最简,仅由此文分享个人想法,如有错误,还请各位在评论区指正!