C语言数据结构课设:矩阵的运算(转置.求和.求差.矩阵相乘.求逆.数乘),文件读取矩阵

 

#include <stdio.h>
#include <string.h>
#include<stdlib.h>
#include<math.h>

// 定义一个结构体类型,表示一个矩阵

typedef struct matrix
{
    int nrow; // 矩阵的行数
    int ncol; // 矩阵的列数
    double data[10][10]; // 矩阵的数据,最大为 10 x 10
} matrix;

// 定义一个函数,用于显示一个矩阵的内容 


void display_matrix(matrix m)
{
    int i,j;
    // 用两层循环遍历矩阵的每个元素
    for(i=0; i<m.nrow; i++)
    {
        for(j=0; j<m.ncol; j++)
        {
            // 打印矩阵的当前元素,保留小数点后六位
            printf(" %f",m.data[i][j]);
        }
        // 换行
        printf("\n");
    }
}

 // 定义一个函数,用于计算一个矩阵的转置


matrix matrix_t(matrix m)
{
    int i,j;
    matrix c; // 定义一个新的矩阵,用于存储转置结果
    c.nrow=m.ncol; // 转置后的矩阵的行数等于原矩阵的列数
    c.ncol=m.nrow; // 转置后的矩阵的列数等于原矩阵的行数
    // 用两层循环遍历原矩阵的每个元素
    for (i = 0; i < m.nrow; i++)
    {
        for(j = 0; j < m.ncol; j++)
        {
            // 将原矩阵的第 i 行第 j 列的元素赋值给转置后的矩阵的第 j 行第 i 列
            c.data[j][i] = m.data[i][j];
        }
    }
    display_matrix(c); // 调用 display_matrix 函数,显示转置后的矩阵
    return c; // 返回转置后的矩阵
}

 // 定义一个函数,用于计算两个矩阵的加法


matrix matrix_add(matrix a, matrix b)
{
    matrix c; // 定义一个新的矩阵,用于存储加法结果
    c.nrow=a.ncol; // 结果矩阵的行数等于两个矩阵的行数
    c.ncol=a.nrow; // 结果矩阵的列数等于两个矩阵的列数

     int i, j;
    // 用两层循环遍历两个矩阵的每个元素
    for (i = 0; i < a.nrow; i++)
    {
        for(j = 0; j < a.ncol; j++)
        {
            // 将两个矩阵的对应元素相加,赋值给结果矩阵的对应位置
            c.data[i][j]=a.data[i][j]+b.data[i][j];
        }
    }
    display_matrix(c); // 调用 display_matrix 函数,显示加法结果
    return c; // 返回加法结果
}

// 定义一个函数,用于计算两个矩阵的减法


matrix matrix_minus(matrix a, matrix b)
{
    matrix c; // 定义一个新的矩阵,用于存储减法结果
    c.nrow=a.ncol; // 结果矩阵的行数等于两个矩阵的行数
    c.ncol=a.nrow; // 结果矩阵的列数等于两个矩阵的列数

    int i, j;
    // 用两层循环遍历两个矩阵的每个元素
    for (i = 0; i < a.nrow; i++)
    {
        for(j = 0; j < a.ncol; j++)
        {
            // 将两个矩阵的对应元素相减,赋值给结果矩阵的对应位置
            c.data[i][j]=a.data[i][j]-b.data[i][j];
        }
    }
    display_matrix(c); // 调用 display_matrix 函数,显示减法结果
    return c; // 返回减法结果
}

 // 定义一个函数,用于计算两个矩阵的乘法


matrix matrix_mul(matrix a, matrix b)
{
    matrix c; // 定义一个新的矩阵,用于存储乘法结果
    c.nrow=a.ncol; // 结果矩阵的行数等于第一个矩阵的行数
    c.ncol=b.nrow; // 结果矩阵的列数等于第二个矩阵的列数

    int i, j,k;
    // 用三层循环遍历两个矩阵的每个元素
    for (i = 0; i < a.nrow; i++)
    {
        for(j = 0; j < b.ncol; j++)
        {
            double tmp=0; // 定义一个临时变量,用于存储乘法的中间结果
            for(k=0; k<a.ncol; k++)
                // 将第一个矩阵的第 i 行的每个元素与第二个矩阵的第 j 列的每个元素相乘,并累加到临时变量中
                tmp+=a.data[i][k]*b.data[k][j];
            c.data[i][j]=tmp; // 将临时变量的值赋值给结果矩阵的对应位置
        }
    }
    display_matrix(c); // 调用 display_matrix 函数,显示乘法结果
    return c; // 返回乘法结果
}

// 定义一个函数,用于计算一个矩阵的逆


int  matrix_inv(matrix m)
{
    int i,j;
    int ndimen=m.nrow; // 获取矩阵的行数(假设是方阵)
    double a_matrix[3][3]; // 定义一个临时的 3 x 3 矩阵,用于存储计算过程中的结果
     int k, k1, k2, k3,  j2, i2, kme[20], kmf[20]; // 定义一些辅助变量,用于记录矩阵的行列交换
    for (i=0;i<ndimen;i++){
        for(j=0;j<ndimen;j++)
            a_matrix[i][j]=m.data[i][j]; // 将原矩阵的数据复制到临时矩阵中
    }
    double tmp, tmp2, b_tmp[20], c_tmp[20]; // 定义一些临时变量,用于存储计算过程中的中间值

    i2 = j2 = 0; // 初始化 i2 和 j2 为 0

    for (k = 0; k < ndimen; k++) // 从第 0 行开始,遍历每一行
    {
        tmp2 = 0.0; // 初始化 tmp2 为 0.0
        for (i = k; i < ndimen; i++) // 从第 k 行开始,遍历每一行
        {
            for (j = k; j < ndimen; j++) // 从第 k 列开始,遍历每一列
            {
                if (fabs(a_matrix[i][j] ) <= fabs(tmp2)) // 如果当前元素的绝对值小于等于 tmp2
                    continue; // 跳过当前元素
                tmp2 = a_matrix[i][j];//最大值 // 否则,将当前元素赋值给 tmp2,作为最大值
                i2 = i; // 记录最大值所在的行号
                j2 = j; // 记录最大值所在的列号
            }
        }
        if (i2 != k) // 如果最大值所在的行号不等于 k
        {
            for (j = 0; j < ndimen; j++) // 遍历每一列
            {
                tmp = a_matrix[i2][j]; // 交换第 i2 行和第 k 行的元素
                a_matrix[i2][j] = a_matrix[k][j];
                a_matrix[k][j] = tmp;
            }
        }
        if (j2 != k) // 如果最大值所在的列号不等于 k
        {
            for (i = 0; i < ndimen; i++) // 遍历每一行
            {
                tmp = a_matrix[i][j2]; // 交换第 j2 列和第 k 列的元素
                a_matrix[i][j2] = a_matrix[i][k];
                a_matrix[i][k] = tmp;
            }
        }
        kme[k] = i2; // 记录第 k 次交换的行号
        kmf[k] = j2; // 记录第 k 次交换的列号
        for (j = 0; j < ndimen; j++) // 遍历每一列
        {
            if (j == k) // 如果是第 k 列
            {
                b_tmp[j] = 1.0 / tmp2; // 将最大值的倒数赋值给 b_tmp[j]
                c_tmp[j] = 1.0; // 将 1.0 赋值给 c_tmp[j]
            }
            else // 如果不是第 k 列
            {
                b_tmp[j] = -a_matrix[k][j] / tmp2; // 将第 k 行第 j 列的元素的相反数除以最大值赋值给 b_tmp[j]
                c_tmp[j] = a_matrix[j][k]; // 将第 j 行第 k 列的元素赋值给 c_tmp[j]
            }
            a_matrix[k][j] = 0.0; // 将第 k 行第 j 列的元素赋值为 0.0
            a_matrix[j][k] = 0.0; // 将第 j 行第 k 列的元素赋值为 0.0
        }
        for (i = 0; i < ndimen; i++) // 遍历每一行
        {
            for (j = 0; j < ndimen; j++) // 遍历每一列
            {
                a_matrix[i][j] = a_matrix[i][j] + c_tmp[i] * b_tmp[j]; // 将第 i 行第 j 列的元素加上 c_tmp[i] 乘以 b_tmp[j] 的结果
            }
        }
    }
    for (k3 = 0; k3 < ndimen;  k3++) // 从第 0 行开始,遍历每一行
    {
        k  = ndimen - k3 - 1; // 计算当前行号的倒序
        k1 = kme[k]; // 获取第 k 次交换的行号
        k2 = kmf[k]; // 获取第 k 次交换的列号
        if (k1 != k) // 如果行号不等于 k
        {
            for (i = 0; i < ndimen; i++) // 遍历每一行
            {
                tmp = a_matrix[i][k1]; // 交换第 k1 列和第 k 列的元素
                a_matrix[i][k1] = a_matrix[i][k];
                a_matrix[i][k] = tmp;
            }
        }
        if (k2 != k) // 如果列号不等于 k
        {
            for(j = 0; j < ndimen; j++) // 遍历每一列
            {
                tmp = a_matrix[k2][j]; // 交换第 k2 行和第 k 行的元素
                a_matrix[k2][j] = a_matrix[k][j];
                a_matrix[k][j] = tmp;
            }
        }
    }
    for (i=0;i<ndimen;i++){ // 遍历每一行
        for(j=0;j<ndimen;j++) // 遍历每一列
            printf(" %f",a_matrix[i][j]); // 打印临时矩阵的元素,保留小数点后六位
        printf("\n"); // 换行
    }
    return (0); // 返回 0,表示函数执行成功
}

// 定义一个函数,用于计算一个矩阵与一个数的乘法 


matrix matrix_numMulti(matrix a){
        int n; // 定义一个整型变量,用于存储输入的数
    matrix c; // 定义一个新的矩阵,用于存储乘法结果
    c.nrow=a.nrow; // 结果矩阵的行数等于原矩阵的行数
    c.ncol=a.ncol; // 结果矩阵的列数等于原矩阵的列数

    int i, j;
    printf("请输入一个数:"); // 提示用户输入一个数
    scanf("%d",&n); // 从标准输入读取一个整数,赋值给 n
    for (i = 0; i < a.nrow; i++) // 遍历原矩阵的每一行
    {
        for(j = 0; j < a.ncol; j++) // 遍历原矩阵的每一列
        {
            c.data[i][j]=a.data[i][j]*n; // 将原矩阵的第 i 行第 j 列的元素乘以 n,赋值给结果矩阵的对应位置
        }
    }
    display_matrix(c); // 调用 display_matrix 函数,显示乘法结果
    return c; // 返回乘法结果

}

// 定义一个函数,用于显示程序的功能菜单

void interface()
{
    printf("----------------------------————————————————————————————\n");
    printf("----------------------------————————————————————————————\n");
    printf("           1.显示A、B矩阵                       2.求矩阵A的转置\n"); // 1.显示两个已定义的矩阵 A 和 B,2.计算并显示矩阵 A 的转置
    printf("           3.求两矩阵的和                       4.求两矩阵的差\n"); // 3.计算并显示矩阵 A 和 B 的加法结果,4.计算并显示矩阵 A 和 B 的减法结果
    printf("           5.求两矩阵的积                       6.求矩阵A的逆\n"); // 5.计算并显示矩阵 A 和 B 的乘法结果,6.计算并显示矩阵 A 的逆
    printf("           7.数乘                               8.退出程序  \n"); // 7.提示用户输入一个数,计算并显示矩阵 A 与该数的乘法结果,8.退出程序
     printf("           0.查看程序功能                                    \n"); // 0.重新显示程序的功能菜单
    printf("----------------------------————————————————————————————\n");
    printf("----------------------------————————————————————————————\n");
}


int main()
{
//文件读取,int dim1,dim2; int ta[3][3];int tb[3][3]; 
/*

oo.txt 文件
3
1 2 3
5 4 3
6 5 4
3
2 5 4
3 4 5
9 6 4
*/
    int dim1,dim2; // 定义一个整型变量,表示矩阵的维度(假设是 3 x 3 的方阵)
    int ta[3][3]; // 定义一个二维数组,表示矩阵 A 的数据
    int tb[3][3];
    int i,j;


    FILE *fp;
    fp=fopen("oo.txt","r");
    if(fp==NULL){
        printf("无法打开文件!");
        return 0;
    }

        fscanf(fp,"%d",&dim1);
        for(i=0;i<3;i++){
            for(j=0;j<3;j++){
            fscanf(fp,"%d",&ta[i][j]);
            }
    }
    
    fscanf(fp,"%d",&dim2);
    for(i=0;i<3;i++){
            for(j=0;j<3;j++){
            fscanf(fp,"%d",&tb[i][j]);
            }
    }
//可输出查看是否成功读取
    /* for(i=0;i<3;i++){
            for(j=0;j<3;j++){
            printf("%d",ta[i][j]);
            }
            printf("\n");
    }
*/
    fclose(fp);


    matrix a,b; // 定义两个矩阵类型的变量,分别表示矩阵 A 和 B
    a.nrow=a.ncol=dim1; // 设置矩阵 A 的行数和列数为 dim
    for(i=0; i<a.nrow; i++) // 遍历每一行
    {
        for(j=0; j<a.ncol; j++) // 遍历每一列
        {
            a.data[i][j]=(double)(ta[i][j]); // 将二维数组的数据赋值给矩阵 A 的数据
        }
    }
   

    b.nrow=b.ncol=dim2; // 设置矩阵 B 的行数和列数为 dim
    for(i=0; i<b.nrow; i++) // 遍历每一行
    {
        for(j=0; j<b.ncol; j++) // 遍历每一列
        {
            b.data[i][j]=tb[i][j]; // 将二维数组的数据赋值给矩阵 B 的数据
        }
    }

    interface(); // 调用 interface 函数,显示程序的功能菜单
    int choice=0; // 定义一个整型变量,用于存储用户的选择
    while(choice>=0&&choice<8) // 当用户的选择在 0 到 7 之间时,循环执行
    {
        printf("\n请选择:"); // 提示用户选择
        scanf("%d",&choice); // 从标准输入读取一个整数,赋值给 choice
        switch(choice) // 根据 choice 的值,执行相应的操作
        {
        case 0: // 如果 choice 为 0
            interface(); // 重新显示程序的功能菜单
            break; // 跳出 switch 语句
        case 1: // 如果 choice 为 1
            printf("A:\n"); // 打印 A
            display_matrix(a); // 调用 display_matrix 函数,显示矩阵 A
            printf("B:\n"); // 打印 B
            display_matrix(b); // 调用 display_matrix 函数,显示矩阵 B
            break; // 跳出 switch 语句
        case 2: // 如果 choice 为 2
            printf("A的转置:\n"); // 打印 A 的转置
            matrix_t(a); // 调用 matrix_t 函数,计算并显示矩阵 A 的转置
            break; // 跳出 switch 语句
        case 3: // 如果 choice 为 3
            printf("A+B:\n"); // 打印 A + B
            matrix_add(a,b); // 调用 matrix_add 函数,计算并显示矩阵 A 和 B 的加法结果
            break; // 跳出 switch 语句
        case 4: // 如果 choice 为 4
            printf("A-B:\n"); // 打印 A - B
            matrix_minus(a,b); // 调用 matrix_minus 函数,计算并显示矩阵 A 和 B 的减法结果
            break; // 跳出 switch 语句
        case 5: // 如果 choice 为 5
            printf("AxB:\n"); // 打印 A x B
            matrix_mul(a,b); // 调用 matrix_mul 函数,计算并显示矩阵 A 和 B 的乘法结果
            break; // 跳出 switch 语句
        case 6: // 如果 choice 为 6
            printf("A的逆:\n"); // 打印 A 的逆
            matrix_inv(a); // 调用 matrix_inv 函数,计算并显示矩阵 A 的逆
            break; // 跳出 switch 语句
        case 7: // 如果 choice 为 7
            printf("A的数乘"); // 打印 A 的数乘
            matrix_numMulti(a); // 调用 matrix_numMulti 函数,提示用户输入一个数,计算并显示矩阵 A 与该数的乘法结果
        default: // 如果 choice 不在 0 到 7 之间
            printf("成功退出!\n"); // 打印退出信息
        }
    }
    return 0; // 返回 0,表示程序正常结束
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值