数据结构之稀疏矩阵(稀疏矩阵输出到文件,从文件恢复稀疏矩阵)

 

 

 

 

 

 

 

 

稀疏矩阵,可用于矩阵的压缩,如下图(也是该代码的执行结果):


 


稀疏矩阵特点:首行中每一列依次代表:原矩阵行数、列数 和某行某列的值。

下面稀疏数组表示:在原矩阵(下标从0开始)第2行第3列的值为1,以此类推。

 

方法详解:

 

private static void sparseArrayCalc(int row, int col, int value) throws IOException {
        // 创建8*8棋盘,这里只是一个测试用例,chessarray可以自定义传入。这里的赋值1,2代表黑白棋。
        int chessarray[][] = new int[8][8];
        chessarray[2][3] = 1;
        chessarray[3][4] = 2;
        chessarray[4][5] = 1;
        chessarray[row][col] = value;
      int length=chessarray.length;//记录棋盘矩阵的大小
        // 棋盘中的棋子数   //这里是获取矩阵中的有效棋子的个数
        int sum = 0;
        for (int chessarr[] : chessarray) {
            for (int data : chessarr) {
                System.out.printf("%d\t", data);
                if (data != 0) {
                    sum++;//拿到矩阵中非0的值的个数
                }
            }
            System.out.println();
        }

        // 构建稀疏矩阵压缩保存棋盘
        int sparsearray[][] = new int[sum + 1][3];//此位置的sum+1是因为稀疏数组里,要加一行来记录原矩阵的行数、列数和值
        sparsearray[0][0] = length;//原矩阵有11行
        sparsearray[0][1] = length;//11列
        sparsearray[0][2] = sum;//sum个非0数字
        int count = 0;//count用来作为sparsearray的索引计数。
        for (int i = 0; i < length; i++) {//遍历原矩阵
            for (int j = 0; j < length; j++) {
                if (chessarray[i][j] != 0) {//如果原棋盘矩阵第i行j列不等于0,说明有非0值
                    count++;//这里首先执行count++,因为稀疏矩阵第一行是用于存储,棋盘矩阵的行数,列数和值的。(也可以将上面count初始化为1,最后++)
                    sparsearray[count][0] = i;//记录第i行
                    sparsearray[count][1] = j;//记录第j行
                    sparsearray[count][2] = chessarray[i][j];//存储第i行第j列的值
                }
            }
        }
        count = 0;//count在下面别有用处,所以将其重新赋值0
        System.out.println("chessarray的稀疏矩阵为:");
        // 保存稀疏棋盘到文件中,这里进行io操作,将稀疏棋盘写到当前目录的test.txt中
        FileWriter fw = new FileWriter("test.txt");//按字符将文件写入test.txt中
        BufferedWriter bw = new BufferedWriter(fw);//
     //这里是操作io流的基本操作
        for (int sparsearr[] : sparsearray) {
            System.out.printf("%d\t%d\t%d\t\n", sparsearr[0], sparsearr[1], sparsearr[2]);
            for (int data : sparsearr) {
                bw.write(String.valueOf(data) + "\t");//将每个sparsearr数组中的行列值写入到文件
            }
            bw.newLine();//换行(与/n是不同的)
        }
        bw.close();//这里缓冲流关闭之前,会将缓冲区写入的数据,刷新到文件
        fw.close();

        // 从文件中读取稀疏棋盘并恢复棋盘
        System.out.println("===================================");
        int chessarray2[][] = new int[sparsearray[0][0]][sparsearray[0][1]];//这里定义恢复后的棋盘矩阵,其行列大小为稀疏矩阵的首行2列
        FileReader fr = new FileReader("test.txt");//文件字符输入流
        BufferedReader br = new BufferedReader(fr);//缓冲字符流
        String str;//用于接收缓冲区读入的字符
        String datas[] = new String[sum+1];//sum+1表示整个稀疏矩阵的大小,1代表首行
        while ((str = br.readLine()) != null) {//按行读入字符
            //System.out.println(str);
            datas[count] = str;//将每一行放入datas数组中
            count++;        
        }
        br.close();fr.close();//关闭流
        count = 0;//此变量第三次使用,都用于计数。
        String da[]=new String[3*(sum+1)];//由于输入流读入是按行,这里是为了存储每一个信息,每行有3列;
        String d[];//临时保存棋子的位置
        for (String data : datas) {
            d=data.split("\t");//将每一行形如 2 3 1,将一行字符串,拆分为行列数和棋子数
            for(String s:d) {
                da[count]=s;//再将每个单独行数、列数、棋子保存到da数组中
                count++;
            }
        }
        //这里是将稀疏矩阵中的第三列(具体的棋子黑还是白),恢复到原棋盘8x8的位置上
        for(int i=3;i<da.length;i+=3) {
            chessarray2[Integer.parseInt(da[i])][Integer.parseInt(da[i+1])]=Integer.parseInt(da[i+2]);
        }
        
        System.out.println("从文件中读取稀疏矩阵-->恢复后的棋盘:");
        for (int chessarr[] : chessarray2) {
            for (int data : chessarr) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }
    }

 

posted @ 2020-04-16 20:03  两仪子  阅读(1042)  评论(0编辑  收藏  举报