Java数据结构学习之稀疏矩阵-day01

1:稀疏矩阵(数组)思想

以如图一个矩阵为例:有2、6、7、3、1、2、8、5、9、0这几个值,但大部分都是0,也就是无用数据,为了压缩矩阵,将该矩阵的大小(行、列数据)和非0数据的值和位置存储到一个数组中,这就是稀疏矩阵思想。

这里写图片描述

稀疏后的矩阵(数组)
[0]6(行数)8(列数)9(有9个值)
所在行所在列
[1]112
[2]156
[3]187
[4]231
[5]332
[6]373
[7]468
[8]545
[9]629

如上,有a[0]到a[9]一共10个向量。除了a[0]用来存储表格属性信息之外,a[1]到a[9]保存了数据所在的行、列和数据值,这10个向量组成的矩阵就是稀疏矩阵。

2:稀疏矩阵的Java实现

public class Sparse {

    public static void main(String[] args) {
        int[][] before = new int[][]{{1, 0, 0, 0, 5}, {0, 9, 6, 0, 0}, {-1, 0, 9, 0, 7}, {1, 2, 3, 0, 0}};
        int[][] a = sparse(before);

        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i].length; j++) {
                System.out.print(a[i][j] + " ");
            }
            System.out.println();
        }

    }

    public static int[][] sparse(int[][] beforeSparse) {

        int validNumber = 0;//定义有效数据个数;

        for (int i = 0; i < beforeSparse.length; i++) {//获取有效数据长度
            for (int j = 0; j < beforeSparse[i].length; j++) {
                if (beforeSparse[i][j] != 0) {
                    validNumber++;//有效数据的个数同样也是是稀疏矩阵的行数;
                }
            }
        }
        int[][] afterSparse = new int[validNumber + 1][3];
        //获得有效数据的数量之后,就可以定义转制后系数矩阵的大小,稀疏矩阵大小为(数据量+1)*(3)
        afterSparse[0][0] = beforeSparse.length;
        afterSparse[0][1] = beforeSparse[0].length;
        afterSparse[0][2] = validNumber;
        //这三步将原矩阵的大小先存到稀疏矩阵的第0行的1、2、3列;
        int k = 1;
        for (int i = 0; i < beforeSparse.length; i++) {
            for (int j = 0; j < beforeSparse[i].length; j++) {//通过两个for循环拿到原矩阵中非0的数据值;
                if (beforeSparse[i][j] != 0) {
                    afterSparse[k][0] = i;
                    afterSparse[k][1] = j;
                    afterSparse[k][2] = beforeSparse[i][j];
                    //如果该数据值不为0,则将它的行、列、值信息一起填至k行的0、1、2位置;
                    //注意,k应该从1开始,因为稀疏矩阵的第0行已经存储了原矩阵的属性信息;
                    k++;
                }
            }
        }

        return afterSparse;
    }
}
输出结果如下(注意最后一组,后面犯的错误就会导致不停输出最后一组):
4 5 10 
0 0 1 
0 4 5 
1 1 9 
1 2 6 
2 0 -1 
2 2 9 
2 4 7 
3 0 1 
3 1 2 
3 2 3 

个人所犯错误记录:

for (int i = 0; i < beforeSparse.length; i++) {
            for (int j = 0; j < beforeSparse[i].length; j++) {
                //通过两个for循环拿到原矩阵中非0的数据值;
                if (beforeSparse[i][j] != 0) {
                    for (int k = 1; k < afterSparse.length; k++) {
                    afterSparse[k][0] = i;
                    afterSparse[k][1] = j;
                    afterSparse[k][2] = beforeSparse[i][j];
                    }
                    //如果该数据值不为0,则将它的行、列、值信息一起填至k行的0、1、2位置;
                    //注意,k应该从1开始,因为稀疏矩阵的第0行已经存储了原矩阵的属性信息;
                }
            }
            }
                    /*(输出结果如下(只有正确答案的最后一组):
                    4 5 10 
                    3 2 3
                    3 2 3
                    3 2 3
                    3 2 3
                    3 2 3 
                    3 2 3 
                    3 2 3
                    3 2 3 
                    3 2 3
                    3 2 3 
                    */

如图所示,错误使用了三个for循环来试图给稀疏矩阵赋值,但其实程序在进入第三个for循环后,只要原矩阵遍历到不为0的元素,都会给afterSprase矩阵重复赋值k=1k=afterSprase.length次;例如在原矩阵[0,0]处元素为1,符合条件进入第三个循环,在该处for循环就给稀疏数组赋值了afterSprase.length-1次,而在第三个for循环结束后,当检测到又有一个元素不为0时又会重复赋值afterSprase.length-1,因此这是不正确的,最后显示的结果将会是最后一个非0数据处的10次重复(前面输出结果的最后一组数据)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值