对称矩阵的压缩存储

实验目的:熟练掌握对称矩阵压缩存储的方法,并能运用此方法进行实际应用。
实验内容:对于n×n阶的对称矩阵,其元素分布的特点是a[i][j]=a[j][i],在存储时,只需压缩存储对称矩阵的上三角或下三角元素,但两个对称矩阵相乘的结果不一定是对称矩阵。
实验要求:
(1)创建名为kcsj14.cpp的文件,在其中编写两个对称矩阵相乘的程序。
(2)分别输入对称矩阵的元素。
(3)将这两个矩阵相乘,所得结果存入一个n×n阶的矩阵中,输出存放结果的矩阵。
(4)若输出为上三角或下三角矩阵,则需对其进行压缩存储。


import java.util.Scanner;

class Matrix {
    // 定义矩阵大小
    int N;
    // 这里用一维数组存储对称矩阵压缩后的下上角
    int[] m;
    // 带参数的构造函数
    public Matrix(int N, int[] M) {
        this.N = N;
        this.m = M;
    }
    // 做矩阵乘法
    int[][] mul(Matrix M) {
        // 声明N * N的二维数组存放计算结果
        int[][] ans = new int[N][N];
        for(int i = 0; i < N; i++) {
            for(int j = 0; j < N; j++) {
                ans[i][j] = 0;
                for(int k = 0; k < N; k++) {
                    // 矩阵乘法ans[i][j] = ans[i][j] + M1[i][k] * M2[k][j];
                    // 这里将上式中的M1[i][k]和M2[k][j]分开计算
                    int temp = 1;
                    if(i >= k) temp = temp * m[i*(i+1)/2 + k];
                    else temp = temp * m[k*(k+1)/2 + i];

                    if(k >= j) temp = temp * M.m[k*(k+1)/2 + j];
                    else temp = temp * M.m[j*(j+1)/2 + k];

                    ans[i][j] = ans[i][j] + temp;
                }
            }
        }
        return ans;
    }
    // 判断矩阵是上三角、下三角、对称矩阵或者常规矩阵
    static int judge(int[][] M, int N) {
        // flag[0]为真表示是上三角,flag[1]表示下三角,flag[2]表示对称矩阵
        boolean[] flag = new boolean[3];
        // 初始化为全真
        flag[0] = flag[1] = flag[2] = true;
        for(int i = 0; i < N; i++) {
            for(int j = 0; j < N; j++) {
                // 当下三角部分不全为0时,该矩阵不是上三角矩阵
                if(i > j && M[i][j] != 0) flag[0] = false;
                // 当上三角部分不全为0时,该矩阵不是下三角矩阵
                if(i < j && M[i][j] != 0) flag[1] = false;
                // 当M[i][j] != M[j][i]时,该矩阵不是对称矩阵
                if(M[i][j] != M[j][i]) flag[2] = false;
            }
        }
        // 返回判断结果1表示上三角、2表示下三角、3表示对称矩阵、4表示常规矩阵
        if(flag[0]) return 1;
        else if(flag[1]) return 2;
        else if(flag[2]) return 3;
        else return 4;
    }
    // 按类型输出矩阵
    static void printMatrix(int[][] M, int status, int N) {
        switch(status) {
            case 1:{    // 压缩输出上三角矩阵
                System.out.println("(此矩阵为上三角矩阵,压缩后如下)");
                int[] out = new int[N*(N+1)/2];
                for(int i = 0; i < N; i++) {
                    for(int j = i; j < N; j++) {
                        // 上三角与原矩阵的对应关系为M[i][j] = m[i*(2*N-i+1)/2 + j - i];
                        out[i*(2*N-i+1)/2 + j - i] = M[i][j];
                    }
                }
                for(int i = 0; i < N; i++) {
                    for(int j = 0; j < N; j++) {
                        if(i <= j) System.out.printf("%10d", out[i*(2*N-i+1)/2 + j - i]);
                        else System.out.printf("          ");
                    }
                    System.out.println();
                }
                break;
            }
            case 2:{    // 压缩输出下三角矩阵
                System.out.println("(此矩阵为下三角矩阵,压缩后如下)");
                int[] out = new int[N*(N+1)/2];
                for(int i = 0; i < N; i++) {
                    for(int j = 0; j <= i; j++) {
                        // 下三角矩阵与原矩阵的对应关系为M[i][j] = m[i*(i+1)/2 + j];,下同。
                        out[i*(i+1)/2 + j] = M[i][j];
                    }
                }
                for(int i = 0; i < N; i++) {
                    for(int j = 0; j <= i; j++) {
                        System.out.printf("%10d", out[i*(i+1)/2 + j]);
                    }
                    System.out.println();
                }
                break;
            }
            case 3:{    // 压缩输出对称矩阵
                System.out.println("(该矩阵为对称矩阵,压缩后的下三角部分如下)");
                int[] out = new int[N*(N+1)/2];
                for(int i = 0; i < N; i++) {
                    for(int j = 0; j <= i; j++) {
                        // 将矩阵压缩,同上
                        out[i*(i+1)/2 + j] = M[i][j];
                    }
                }
                for(int i = 0; i < N; i++) {
                    for(int j = 0; j <= i; j++) {
                        System.out.printf("%10d", out[i*(i+1)/2 + j]);
                    }
                    System.out.println();
                }
                break;
            }
            case 4:{    // 输出常规矩阵
                System.out.println("(该矩阵为常规矩阵)");
                for(int i = 0; i < N; i++) {
                    for(int j = 0; j < N; j++) {
                        System.out.printf("%10d", M[i][j]);
                    }
                    System.out.println();
                }
                break;
            }
            default:{
                System.out.println("错误: 传入的状态码有误!!");
            }
        }
    }
}

public class kcsj14 {
    public static void main (String args[]) {
        Scanner sc = new Scanner(System.in);
        int N;

        System.out.print("需要计算的矩阵阶数: ");
        N = sc.nextInt();
        int[] M1 = new int[N*(N+1)/2];
        int[] M2 = new int[N*(N+1)/2];

        System.out.println("输入A矩阵的下三角部分:");
        for(int i = 0; i < N; i++) {
            for(int j = 0; j <= i; j++) {
                // 下三角矩阵的对应关系为M[i][j] = m[i*(i+1)/2 + j];
                M1[i*(i+1)/2 + j] = sc.nextInt();
            }
        }
        // 声明A矩阵
        Matrix A = new Matrix(N, M1);

        System.out.println("输入B矩阵的下三角部分:");
        for(int i = 0; i < N; i++) {
            for(int j = 0; j <= i; j++) {
                // 下三角矩阵的对应关系为M[i][j] = m[i*(i+1)/2 + j];
                M2[i*(i+1)/2 + j] = sc.nextInt();
            }
        }
        // 声明B矩阵
        Matrix B = new Matrix(N, M2);

        // 存放结果
        int[][] ans = A.mul(B);
        System.out.print("A * B的计算结果为: ");
        Matrix.printMatrix(ans, Matrix.judge(ans, A.N), A.N);
    }
}



  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值