在写矩阵运算器,伴随矩阵部分按照常规数学思路进行求解,先求余子式(用了新一个数组储存,去掉i行j列后其余数据向内挪填补空缺)代数余子式再转置,但得到的结果有问题,没有找到错误位置。
#include
#include
#include
double **chushihua(int m,int n){
double **a=NULL;
int i,j;
a=(double **)malloc((m+1)*sizeof(double*));
for(i=0;i1)*sizeof(double));
}//申请动态内存
printf("请输入矩阵数据:\n");
for(i=0;i0;j"%lf",&a[i][j]);
}
}
return a;
}
void transpose(double **a,int m,int n){
int i,j;
for(i=0;i0;j"%.2lf\t",a[j][i]);
}
printf("\n");
}
}
void dayin(double **matrix,int m,int n){
int i,j;
for(i=0;i0;j"%.2lf\t",matrix[i][j]);
}
printf("\n");
}
}
int main(){
int m,n,caozuo,i,j;
double **matrix1=NULL;
printf("请输入矩阵的行数:");
scanf("%d",&m); //m为第一个矩阵的行数
printf("请输入矩阵的列数:");
scanf("%d",&n); //n为第一个矩阵的列数
matrix1=chushihua(m,n);
printf("请输入对应的数字编号选择您想要进行的操作:\n1.求转置矩阵;\n2.两个矩阵相加;\n3.求两个矩阵的乘积;\n4.求满足条件的方阵A的伴随矩阵A * 、逆矩阵A -1;\n5.退出\n");
scanf("%d",&caozuo);
if(caozuo==1){
printf("转置后矩阵为:\n");
transpose(matrix1,m,n);
}
else if(caozuo==2){
double matrix2[m][n];
printf("请输入与其相加的矩阵数据:\n");
for(i=0;i0;j"%lf",&matrix2[i][j]);
}
}
printf("相加后矩阵为:\n");
for(i=0;i0;j"%.2lf\t",matrix1[i][j]+matrix2[i][j]);
}
printf("\n");
}
}
else if(caozuo==3){
int col,k;
double **matrix3=NULL,**matrix4=NULL;
printf("与之相乘的矩阵的行数与第一个矩阵列数相同。\n");
printf("请输入与之相乘的矩阵的列数:");
scanf("%d",&col);
matrix3=(double **)malloc((n+1)*sizeof(double*));
for(i=0;i1)*sizeof(double));
}
matrix3=chushihua(n,col);
double multi[m][col],sum;
printf("相乘后矩阵为:\n");
for(i=0;i0;j 0;
for(k=0;k"%.2lf\t",multi[i][j]);
}
printf("\n");
}
}
else if(caozuo==4){
int t,k,row;
double sum1,sum2;
if(m!=n){
printf("原矩阵行列数不等,无法求伴随矩阵及逆矩阵,请输入新矩阵的行列数:\n");
scanf("%d",&row);
double matrix4[row][row],follow[row][row],yuzishi[row-1][row-1];
printf("请输入矩阵数据:\n");
for(i=0;i0;j"%lf",&matrix4[i][j]);
}
}//原行列数不等的建立新数组储存新矩阵
for(i=0;i0;j0;k0;t-1;k++){
for(t=0;t1][t];
}//超过i行的向上移一行
}
for(k=0;k-1;t++){
yuzishi[k][t]=matrix4[k][t+1];
}//超过j列的向左移一列
}
for(k=i;k-1;k++){
for(t=j;t-1;t++){
yuzishi[k][t]=matrix4[k+1][t+1];
}//i行j列外向内移一个
}//求出余子式
for(k=0;k-1;k++){
if(k==0){
sum1=yuzishi[0][0];
sum2=yuzishi[0][row-1];
}
else if(k!=0){
sum1*=yuzishi[k][k];//正对角线之积
sum2*=yuzishi[k][row-k-1];//反对角线之积
}
}
if((i+j)%2==0){
follow[i][j]=sum1-sum2;
}
else{
follow[i][j]=sum2-sum1;
}//求出代数余子式的值
}//原矩阵中一个数值的代数余子式求解完毕
}
printf("伴随矩阵为:\n");
for(i=0;i0;j"%.2lf\t",follow[j][i]);//进行转置,得到伴随矩阵
}
printf("\n");
}
}
else{
row=m;
double matrix4[row][row],yuzishi[row-1][row-1],follow[row][row];
for(i=0;i0;j0;i0;j0;k0;t-1;k++){
for(t=0;t1][t];
}//超过i行的向上移一行
}
for(k=0;k-1;t++){
yuzishi[k][t]=matrix4[k][t+1];
}//超过j列的向左移一列
}
for(k=i;k-1;k++){
for(t=j;t-1;t++){
yuzishi[k][t]=matrix4[k+1][t+1];
}//i行j列外向内移一个
}//求出余子式
for(k=0;k-1;k++){
if(k==0){
sum1=yuzishi[0][0];
sum2=yuzishi[0][row-1];
}
else if(k!=0){
sum1*=yuzishi[k][k];//正对角线之积
sum2*=yuzishi[k][row-k-1];//反对角线之积
}
}
if((i+j)%2==0){
follow[i][j]=sum1-sum2;
}
else{
follow[i][j]=sum2-sum1;
}//求出代数余子式的值
}//原矩阵中一个数值的代数余子式求解完毕
}
printf("伴随矩阵为:\n");
for(i=0;i0;j"%.2lf\t",follow[j][i]);//进行转置,得到伴随矩阵
}
printf("\n");
}
}//相等的继续运算
}
else if(caozuo==5){
exit(0);
}
else{
printf("错误");
}
}
已经检查很多遍了,还是没找到错误的位置
希望能帮我找出错误,在原有代码上改正,不要通篇换思路,谢谢
你的思路很好,而且完全正确,只是有个小错误,余子式列与行比原矩阵少1,则余子式有row-1行,row-1列,而放在数组中,数组元素是从0开始,所以余子式第一行最后一列表示方法为yuzishi[0][row-2],而不是row-1,row-1代表余子式列数,(row-1)-1才代表数组中的位置,整篇代码,我只改了sum2=yuzishi[0][row-1];与sum2*=yuzishi[k][row-k-1];//反对角线之积,望采纳,修改代码如下:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
double **chushihua(int m,int n){
double **a=NULL;
int i,j;
a=(double **)malloc((m+1)*sizeof(double*));
for(i=0;i<m;i++){
a[i]=(double*)malloc((n+1)*sizeof(double));
}//申请动态内存
printf("请输入矩阵数据:\n");
for(i=0;i<m;i++){
for(j=0;j<n;j++){
scanf("%lf",&a[i][j]);
}
}
return a;
}
void transpose(double **a,int m,int n){
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++){
printf("%.2lf\t",a[j][i]);
}
printf("\n");
}
}
void dayin(double **matrix,int m,int n){
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++){
printf("%.2lf\t",matrix[i][j]);
}
printf("\n");
}
}
int main(){
int m,n,caozuo,i,j;
double **matrix1=NULL;
printf("请输入矩阵的行数:");
scanf("%d",&m); //m为第一个矩阵的行数
printf("请输入矩阵的列数:");
scanf("%d",&n); //n为第一个矩阵的列数
matrix1=chushihua(m,n);
printf("请输入对应的数字编号选择您想要进行的操作:\n1.求转置矩阵;\n2.两个矩阵相加;\n3.求两个矩阵的乘积;\n4.求满足条件的方阵A的伴随矩阵A * 、逆矩阵A -1;\n5.退出\n");
scanf("%d",&caozuo);
if(caozuo==1){
printf("转置后矩阵为:\n");
transpose(matrix1,m,n);
}
else if(caozuo==2){
double matrix2[m][n];
printf("请输入与其相加的矩阵数据:\n");
for(i=0;i<m;i++){
for(j=0;j<n;j++){
scanf("%lf",&matrix2[i][j]);
}
}
printf("相加后矩阵为:\n");
for(i=0;i<m;i++){
for(j=0;j<n;j++){
printf("%.2lf\t",matrix1[i][j]+matrix2[i][j]);
}
printf("\n");
}
}
else if(caozuo==3){
int col,k;
double **matrix3=NULL,**matrix4=NULL;
printf("与之相乘的矩阵的行数与第一个矩阵列数相同。\n");
printf("请输入与之相乘的矩阵的列数:");
scanf("%d",&col);
matrix3=(double **)malloc((n+1)*sizeof(double*));
for(i=0;i<n;i++){
matrix3[i]=(double*)malloc((col+1)*sizeof(double));
}
matrix3=chushihua(n,col);
double multi[m][col],sum;
printf("相乘后矩阵为:\n");
for(i=0;i<m;i++){
for(j=0;j<col;j++){
sum=0;
for(k=0;k<n;k++){
sum+=matrix1[i][k]*matrix3[k][j];
}//循环相加求和计算单个元素
multi[i][j]=sum;//存入乘积数组
printf("%.2lf\t",multi[i][j]);
}
printf("\n");
}
}
else if(caozuo==4){
int t,k,row;
double sum1,sum2;
if(m!=n){
printf("原矩阵行列数不等,无法求伴随矩阵及逆矩阵,请输入新矩阵的行列数:\n");
scanf("%d",&row);
double matrix4[row][row],follow[row][row],yuzishi[row-1][row-1];
printf("请输入矩阵数据:\n");
for(i=0;i<row;i++){
for(j=0;j<row;j++){
scanf("%lf",&matrix4[i][j]);
}
}//原行列数不等的建立新数组储存新矩阵
for(i=0;i<row;i++){
for(j=0;j<row;j++){
for(k=0;k<i;k++){
for(t=0;t<j;t++){
yuzishi[k][t]=matrix4[k][t];
}
}//i行j列内正常复制
for(k=i;k<row-1;k++){
for(t=0;t<j;t++){
yuzishi[k][t]=matrix4[k+1][t];
}//超过i行的向上移一行
}
for(k=0;k<i;k++){
for(t=j;t<row-1;t++){
yuzishi[k][t]=matrix4[k][t+1];
}//超过j列的向左移一列
}
for(k=i;k<row-1;k++){
for(t=j;t<row-1;t++){
yuzishi[k][t]=matrix4[k+1][t+1];
}//i行j列外向内移一个
}//求出余子式
for(k=0;k<row-1;k++){
if(k==0){
sum1=yuzishi[0][0];
sum2=yuzishi[0][row-2];
}
else if(k!=0){
sum1*=yuzishi[k][k];//正对角线之积
sum2*=yuzishi[k][row-k-2];//反对角线之积
}
}
if((i+j)%2==0){
follow[i][j]=sum1-sum2;
}
else{
follow[i][j]=sum2-sum1;
}//求出代数余子式的值
}//原矩阵中一个数值的代数余子式求解完毕
}
printf("伴随矩阵为:\n");
for(i=0;i<row;i++){
for(j=0;j<row;j++){
printf("%.2lf\t",follow[j][i]);//进行转置,得到伴随矩阵
}
printf("\n");
}
}
else{
row=m;
double matrix4[row][row],yuzishi[row-1][row-1],follow[row][row];
for(i=0;i<row;i++){
for(j=0;j<row;j++){
matrix4[i][j]=matrix1[i][j];
}
}
for(i=0;i<row;i++){
for(j=0;j<row;j++){
for(k=0;k<i;k++){
for(t=0;t<j;t++){
yuzishi[k][t]=matrix4[k][t];
}
}//i行j列内正常复制
for(k=i;k<row-1;k++){
for(t=0;t<j;t++){
yuzishi[k][t]=matrix4[k+1][t];
}//超过i行的向上移一行
}
for(k=0;k<i;k++){
for(t=j;t<row-1;t++){
yuzishi[k][t]=matrix4[k][t+1];
}//超过j列的向左移一列
}
for(k=i;k<row-1;k++){
for(t=j;t<row-1;t++){
yuzishi[k][t]=matrix4[k+1][t+1];
}//i行j列外向内移一个
}//求出余子式
for(k=0;k<row-1;k++){
if(k==0){
sum1=yuzishi[0][0];
sum2=yuzishi[0][row-2];
}
else if(k!=0){
sum1*=yuzishi[k][k];//正对角线之积
sum2*=yuzishi[k][row-k-2];//反对角线之积
}
}
if((i+j)%2==0){
follow[i][j]=sum1-sum2;
}
else{
follow[i][j]=sum2-sum1;
}//求出代数余子式的值
}//原矩阵中一个数值的代数余子式求解完毕
}
printf("伴随矩阵为:\n");
for(i=0;i<row;i++){
for(j=0;j<row;j++){
printf("%.2lf\t",follow[j][i]);//进行转置,得到伴随矩阵
}
printf("\n");
}
}//相等的继续运算
}
else if(caozuo==5){
exit(0);
}
else{
printf("错误");
}
}
正确计算运行截图如下:
c语言——矩阵运算器
借鉴或者直接用都可以、
#include<stdio.h>
#include<stdlib.h>
int n,m;
float **a;//运用二重指针,避免二维数组做函数参数时长度未定情况 ;但是要先申请空间
void input() {
int i,j;
printf("请输入行数:");
scanf("%d",&n);
printf("请输入列数:");
scanf("%d",&m);
printf("请输入元素:\n");
a=(float **)malloc(sizeof(float *)*n);//申请行空间
for(i=0; i<n; i++) {
a[i]=(float *)malloc(sizeof(float)*m);//申请列空间
printf("第%d行:",i+1);
for(j=0; j<m; j++) {
scanf("%f",&a[i][j]);
}
}
}
void output(float **c,int p,int q) {
int i,j;
for(i=0; i<p; i++) {
printf("第%d行:",i+1);
for(j=0; j<q; j++) {
printf("%.1f ",c[i][j]);
}
printf("\n");
}
printf("\n");
}
void transform() {
int i,j;
float b[m][n];
for(i=0; i<n; i++) {
for(j=0; j<m; j++) {
b[j][i]=a[i][j];
}
}
for(i=0; i<m; i++) {//转置行数与列数互换
for(j=0; j<n; j++) {
printf("%.1f ",b[i][j]);
}
printf("\n");
}
printf("\n");
}
void add() {
int i,j;
float c[n][m],d[n][m];//相加维数相同;不需要再定义阶数
printf("请输入元素:\n");
for(i=0; i<n; i++) {
printf("第%d行:",i+1);
for(j=0; j<m; j++) {
scanf("%f",&c[i][j]);
}
}
for(i=0; i<n; i++) {
for(j=0; j<m; j++) {
d[i][j]=a[i][j]+c[i][j];
}
}
printf("相加后的矩阵为:\n");
for(i=0; i<n; i++) {
printf("第%d行:",i+1);
for(j=0; j<m; j++) {
printf("%.1f ",d[i][j]);
}
printf("\n");
}
}
void multiply() {
int i,j,k,r;
float c[m][r],d[n][r];
printf("请输入列数:");//相乘:第一个矩阵列数与第二个矩阵行数相同
scanf("%d",&r);
printf("请输入元素:\n");
for(i=0; i<m; i++) {
printf("第%d行:",i+1);
for(j=0; j<r; j++) {
scanf("%f",&c[i][j]);
}
}
for(i=0; i<n; i++) {
for(j=0; j<r; j++) {
for(k=0; k<m; k++) {
d[i][j]+=a[i][k]*c[k][j];
}
}
}
printf("相乘后的矩阵为:\n");
for(i=0; i<n; i++) {
printf("第%d行:",i+1);
for(j=0; j<r; j++) {
printf("%.1f ",d[i][j]);
}
printf("\n");
}
}
float determinant(float **c,int n) {//按第一行完全展开式计算|A|
float det,t,**temp1;
temp1=(float **)malloc(sizeof(float *)*(n-1));//为储存降阶矩阵开辟空间
for(int p=0; p<n-1; p++) {
temp1[p]=(float *)malloc(sizeof(float)*(n-1));
}
if(n==2) {
det=c[0][0]*c[1][1]-c[0][1]*c[1][0];//作为终止条件; 二阶矩阵直接计算 ;
} else {
for(int i=0; i<n; i++) {
for(int j=0; j<n-1; j++) {//记录第一行元素对应余子式的矩阵
for(int k=0; k<n-1; k++) {
temp1[j][k]=c[j+1][(k>=i)?k+1:k];//若列数小于i则不变;若列数大于等于i则向后移动一列;从而记录余子式的矩阵
}
}
t=determinant(temp1,n-1);//递归计算
if(i%2==0) {//判断余子式的正负;与第一行元素相乘;相加得行列式
det+=c[0][i]*t;
} else {
det-=c[0][i]*t;
}
}
}
return det;
}
float **adjoint(float **c,int n) {//计算每一行每一列的每个元素所对应的余子式,组成A*
float **temp2,**adj;
if(n==2) {
adj=(float **)malloc(sizeof(float *)*n); //为n阶伴随矩阵开辟空间
for(int p=0; p<n; p++) {
adj[p]=(float *)malloc(sizeof(float)*n);
}
adj[0][0]=a[1][1];
adj[0][1]=(-1)*a[1][0];
adj[1][0]=(-1)*a[0][1];
adj[1][1]=a[0][0];
} else {
temp2=(float **)malloc(sizeof(float *)*(n-1)); //为n-1阶矩阵开辟空间
for(int p=0; p<n-1; p++) {
temp2[p]=(float *)malloc(sizeof(float)*(n-1));
}
adj=(float **)malloc(sizeof(float *)*n); //为n阶伴随矩阵开辟空间
for(int p=0; p<n; p++) {
adj[p]=(float *)malloc(sizeof(float)*n);
}
for(int i=0; i<n; i++) {//每行
for(int j=0; j<n; j++) {//每列
for(int k=0; k<n-1; k++) {//n-1阶矩阵
for(int t=0; t<n-1; t++) {
temp2[k][t]=c[(k>=i)?k+1:k][(t>=j)?t+1:t];//剔除元素所在行与列之后的矩阵
}
}
adj[j][i]=determinant(temp2,n-1);//计算代数余子式Aji为 转置 后的
if((i+j)%2==1) {//判断符号(-1)^(i+j)
adj[j][i]=-adj[j][i];
}
}
}
}
return adj;
}
int main() {
float z;
float **adj,**bt;
int flag=1;
do {
printf("初始化矩阵:1\n");
printf("打印矩阵: 2\n");
printf("矩阵转置: 3\n");
printf("矩阵相加: 4\n");
printf("矩阵相乘: 5\n");
printf("矩阵求逆: 6\n");
printf("伴随矩阵: 7\n");
printf("退出程序: 0\n");
int o;
printf("请选择功能:");
scanf("%d",&o);
switch(o) {
case 1:
printf("请输入矩阵内容:\n");
input();
break;
case 2:
printf("矩阵内容为:\n");
output(a,n,m);
break;
case 3:
printf("转置后的矩阵为:\n");
transform();
break;
case 4:
printf("请输入新矩阵:\n");
add();
break;
case 5:
printf("请输入新矩阵:\n");
multiply();
break;
case 6:
bt=adjoint(a,n);
z=determinant(a,n);//返回行列式的值
if(z==0) {//判断是否可逆
printf("\n矩阵不可逆!!\n");
} else {
printf("逆矩阵为:\n");
for(int i=0; i<n; i++) {
printf("第%d行:",i+1);
for(int j=0; j<n; j++) {
printf("%.1f ",bt[i][j]/z);//A逆==A*/|A|
}
printf("\n");
}
}
break;
case 7:
printf("伴随矩阵为:\n");
bt=adjoint(a,n);
output(bt,n,n);
break;
case 0:
flag=0;
printf("感谢使用!!");
break;
default:
printf("\n输入错误,请重新输入!!!!\n\n");
break;
}
} while(flag);
}