大概是燃烧的月亮 2022-12-29 22:43 采纳率: 100%
浏览 136
已结题

急,c语言矩阵运算器伴随矩阵运算结果全是0,请求debug

不知道为什么,算出来行列式为0,伴随矩阵也全是0,改了两个不一样的版本都这样

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
int row;
double hanglieshi(double a[][row],int mi);
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 bansui(double matrix[row][row],int row){
    double tern=0,hls;
    int i,j,k,t,n,m,nn=0,mm=0;
    double follow[row][row]; 
    for(i=0;i<row;i++){
        for(j=0;j<row;j++){
            double tempmatrix[row][row];//用于储存每个元素的余子式 
            n=0;
            m=0;
            for(k=0;k<row;k++){
                for(t=0;t<row;t++){
                    if(k!=i&&t!=j){
                        tempmatrix[n][m++]=matrix[k][t];//求余子式,剔除后复制 
                        if(m==row-1){
                            n++;
                            m=0;//起到循环作用,到最后一列时到下一行,刷新列 
                        }
                    }
                }
            }
            tern=hanglieshi(tempmatrix,row-1);//求这一个数值的行列式 
            follow[nn++][mm]=pow(-1,i+j)*tern;//求代数余子式 
            if(nn==row){
                nn=0;
                mm++;
            }
        }
    }
    printf("伴随矩阵为:\n");
    for(i=0;i<row;i++){
        for(j=0;j<row;j++){
            printf("%.2lf\t",follow[i][j]);
        }
        printf("\n");
    }
    hls=hanglieshi(matrix,row);
    if(hls==0){
        printf("行列式为0,矩阵不可逆。");
         
    }
    else{
        printf("逆矩阵为:\n");
        for(i=0;i<row;i++){
            for(j=0;j<row;j++){
                printf("%.2lf\t",follow[i][j]/hls);
            }
            printf("\n");
        }
    }
}
double hanglieshi(double a[][row],int mi){//用第一排求行列式值 
    int i,j,k;
    double tern=0,jiangjie[row][row];
    if(mi==1){
        tern=a[0][0];
    } //一阶矩阵直接返还 
    else if(mi==2){
        tern=a[0][0]*a[1][1]-a[0][1]*a[1][0];
    }//二阶矩阵进行简便计算 
    else{//高阶矩阵再次降阶 
        for(i=0;i<mi;i++){
            for(j=0;j<row-1;j++){
                for(k=0;k<row-1;k++){
                    if(k<i)
                        jiangjie[j][k]=a[j+1][k];
                    else
                        jiangjie[j][k]=a[j+1][k+1];
                }
            }
            tern+=pow(-1,i)*a[0][i]*hanglieshi(jiangjie,mi-1);
        }
    }
    return tern;
} 
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,flag=0;
    double **matrix1=NULL;
    printf("欢迎使用矩阵运算器!下面开始初始化需要运算的矩阵。\n"); 
    printf("请输入矩阵的行数:");
    scanf("%d",&m); //m为第一个矩阵的行数 
    printf("请输入矩阵的列数:");
    scanf("%d",&n); //n为第一个矩阵的列数 
    matrix1=chushihua(m,n);
    while(flag==0){
    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;
        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 i,j,row;
        double tern,hls;
        if(m!=n){
            printf("原矩阵行列数不等,无法求伴随矩阵及逆矩阵,请输入新矩阵的行列数:\n");
            scanf("%d",&row);
            double follow[row][row],matrix4[row][row];
            printf("请输入矩阵数据:\n");
            for(i=0;i<row;i++){
                for(j=0;j<row;j++){
                    scanf("%lf",&matrix4[i][j]); 
                }
            }
            bansui(matrix4,row);
        }
        else{
            row=m;
            double matrix4[row][row];
            for(i=0;i<row;i++){
                for(j=0;j<row;j++){
                    matrix4[i][j]=matrix1[i][j];
                }
            }
            bansui(matrix4,row);
        }
    }
    else if(caozuo==5){
        exit(0);
    }
    else{
        printf("错误");
    }
    }
}


运行结果及详细报错内容

无报错,只是答案不对

img

我的解答思路和尝试过的方法,不写自己思路的,回答率下降 60%
我想要达到的结果,如果你需要快速回答,请尝试 “付费悬赏”

希望能帮我找出错误,在原有代码上改正,不要通篇换思路,不要给现成代码,谢谢(修改了一些小错,和刚发的时候有点区别,但结果没变)

  • 写回答

7条回答 默认 最新

  • yy64ll826 2022-12-30 09:16
    关注
    
    #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);
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

问题事件

  • 系统已结题 1月7日
  • 已采纳回答 12月30日
  • 修改了问题 12月30日
  • 修改了问题 12月29日
  • 展开全部

悬赏问题

  • ¥15 linux驱动,linux应用,多线程
  • ¥20 我要一个分身加定位两个功能的安卓app
  • ¥15 基于FOC驱动器,如何实现卡丁车下坡无阻力的遛坡的效果
  • ¥15 IAR程序莫名变量多重定义
  • ¥15 (标签-UDP|关键词-client)
  • ¥15 关于库卡officelite无法与虚拟机通讯的问题
  • ¥15 目标检测项目无法读取视频
  • ¥15 GEO datasets中基因芯片数据仅仅提供了normalized signal如何进行差异分析
  • ¥100 求采集电商背景音乐的方法
  • ¥15 数学建模竞赛求指导帮助