算法-稀松数组

稀松数组

1.稀松数组什么?

在一个数组中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该数组为稀疏数组;

如图,一个5*5的数组arr上只有3个有效数值其他22个位置全为无效数值

在这里插入图片描述

2.为什么需要压缩稀松数组?

稀松数组中存在大量的无效数据,占用了很多没有必要占用的空间,使用压缩后就能节省空间。

3.怎么压缩稀松数组?

压缩稀松数组步骤如下:

  • 1.我们得先求出稀松数组有多少个有效数值sum

    遍历数组我们可以得到有效个数为3

  • 2.创建一个sum+1行,3列的数组

    创建一个4*3的数组

  • 3.根据稀松数组往创建好的压缩数组中填值

    • 3.1第一行分别填稀松数组的行,列,有效数值个数

      稀松数组的行为arr.length,列为arr[0].length,有效数值为3

    • 3.2其他位置填稀松数组每个有效值对应的行,列,以及具体的值

经过以上步骤我们就得到了如图所示的压缩过后的数组,可以看到占用的空间从原来的5x5变为了现在都3x4

在这里插入图片描述

4.代码实现

既然压缩稀松数组可以节省空间,那我们来代码实现一下,这里我使用的是java代码

4.1.压缩稀松数组

//1.初始化一个稀松数组并存值
        int[][] chessArr = new int[5][5];
        chessArr[1][2] = 1;
        chessArr[2][3] = 2;
        chessArr[4][1] = 2;

        //打印稀松数组
        System.out.println("打印稀松数组:");
        for (int arr[] : chessArr) {
            for (int data :
                    arr) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }

        //2.将稀松数组进行压缩
        //2.1统计稀松数组的有效值个数
        int sum = 0;

        for (int arr[] : chessArr) {
            for (int data :
                    arr) {
                if (data != 0) {
                    sum++;
                }
            }
        }


        //3创建压缩后的数组
        int[][] sparseArray = new int[sum + 1][3];

        //3.1为压缩后的数组中第一行填值
        sparseArray[0][0] = chessArr.length;
        sparseArray[0][1] = chessArr[0].length;
        sparseArray[0][2] = sum;

        //3.2为其他位置填值
        int count = 0;
        for (int i = 0; i < chessArr.length; i++) {
            for (int j = 0; j < chessArr[0].length; j++) {
                if (chessArr[i][j] != 0) {
                    count++;
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = chessArr[i][j];
                }
            }
        }

        System.out.println("压缩后的数组如下:");
        for (int[] arr :
                sparseArray) {
            for (int data :
                    arr) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }

运行结果:

在这里插入图片描述

4.2.将压缩后的数组存储到磁盘

		//创建一个文件
        File file = new File("map.data");

        //创建流
        FileOutputStream fileOutputStream = new FileOutputStream(file);

        //创建一个容器用来临时存储数组每一行的数据,这个地方直接用String是一样的
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < sparseArray.length; i++) {
            for (int j = 0; j < sparseArray[0].length; j++) {
                //如果当前的值为一行的最后
                if (j == sparseArray[0].length - 1) {
                    //在容器后加入一个换行
                    sb.append(sparseArray[i][j] + "\n");

                    //转换为字节数组
                    byte[] bytes = sb.toString().getBytes();

                    //写入到文件中
                    fileOutputStream.write(bytes, 0, bytes.length);

                    //将容器清空
                    sb.delete(0, sb.length());
                    break;
                }
                sb.append(sparseArray[i][j] + ",");
            }
        }
        fileOutputStream.close();//关闭流

运行结果:

在这里插入图片描述

4.3.将磁盘中压缩后的数组还原为稀松数组

        //创建文件
        File mapFile = new File("map.data");

        //拿到文件的字符流
        FileReader fileReader = new FileReader(mapFile);

        //加入缓冲流
        BufferedReader bufferedReader = new BufferedReader(fileReader);

        //从文件中读取一行
        String s = bufferedReader.readLine();

        //将读取的文本按照符号','进行分割
        String[] split = s.split(",");

        //创建稀松数组
        int[][] chessArr2 = new int[Integer.parseInt(split[0])][Integer.parseInt(split[1])];

        //往稀松数组中填值
        while (true) {

            s = bufferedReader.readLine();
            if (s == null) {
                //关闭流
                bufferedReader.close();
                break;
            }
            split = s.split(",");

            chessArr2[Integer.parseInt(split[0])][Integer.parseInt(split[1])] = Integer.parseInt(split[2]);
        }
        System.out.println("通过文件流还原的数组:");
        
        for (int[] arr :
                chessArr2) {
            for (int data :
                    arr) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }

运行结果:

在这里插入图片描述

4.4完整代码:

package com.gong.sparsearray;

import java.io.*;

/**
 * @author 龚成龙
 */
public class SparseArray {
    public static void main(String[] args) throws IOException {
        //1.初始化一个稀松数组并存值
        int[][] chessArr = new int[5][5];
        chessArr[1][2] = 5;
        chessArr[2][3] = 4;
        chessArr[4][1] = 2;

        //打印稀松数组
        System.out.println("打印稀松数组:");
        for (int arr[] : chessArr) {
            for (int data :
                    arr) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }

        //2.将稀松数组进行压缩
        //2.1统计稀松数组的有效值个数
        int sum = 0;

        for (int arr[] : chessArr) {
            for (int data :
                    arr) {
                if (data != 0) {
                    sum++;
                }
            }
        }


        //3创建压缩后的数组
        int[][] sparseArray = new int[sum + 1][3];

        //3.1为压缩后的数组中第一行填值
        sparseArray[0][0] = chessArr.length;
        sparseArray[0][1] = chessArr[0].length;
        sparseArray[0][2] = sum;

        //3.2为其他位置填值
        int count = 0;
        for (int i = 0; i < chessArr.length; i++) {
            for (int j = 0; j < chessArr[0].length; j++) {
                if (chessArr[i][j] != 0) {
                    count++;
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = chessArr[i][j];
                }
            }
        }


        System.out.println("压缩后的数组如下:");
        for (int[] arr :
                sparseArray) {
            for (int data :
                    arr) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }


        //4.将压缩后的数组存储在文件中
        //创建一个文件
        File file = new File("map.data");

        //创建流
        FileOutputStream fileOutputStream = new FileOutputStream(file);

        //创建一个容器用来临时存储数组每一行的数据,这个地方直接用String是一样的
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < sparseArray.length; i++) {
            for (int j = 0; j < sparseArray[0].length; j++) {
                //如果当前的值为一行的最后
                if (j == sparseArray[0].length - 1) {
                    //在容器后加入一个换行
                    sb.append(sparseArray[i][j] + "\n");

                    //转换为字节数组
                    byte[] bytes = sb.toString().getBytes();

                    //写入到文件中
                    fileOutputStream.write(bytes, 0, bytes.length);

                    //将容器清空
                    sb.delete(0, sb.length());
                    break;
                }
                sb.append(sparseArray[i][j] + ",");
            }
        }
        fileOutputStream.close();//关闭流

        //将磁盘中压缩后的数组还原为稀松数组
        //创建文件
        File mapFile = new File("map.data");

        //拿到文件的字符流
        FileReader fileReader = new FileReader(mapFile);

        //加入缓冲流
        BufferedReader bufferedReader = new BufferedReader(fileReader);

        //从文件中读取一行
        String s = bufferedReader.readLine();

        //将读取的文本按照符号','进行分割
        String[] split = s.split(",");

        //创建稀松数组
        int[][] chessArr2 = new int[Integer.parseInt(split[0])][Integer.parseInt(split[1])];

        //往稀松数组中填值
        while (true) {

            s = bufferedReader.readLine();
            if (s == null) {
                //关闭流
                bufferedReader.close();
                break;
            }
            split = s.split(",");

            chessArr2[Integer.parseInt(split[0])][Integer.parseInt(split[1])] = Integer.parseInt(split[2]);
        }
        System.out.println("通过文件流还原的数组:");

        for (int[] arr :
                chessArr2) {
            for (int data :
                    arr) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值