稀疏数组的介绍与Java代码实现

1、基本介绍

当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。

稀疏数组的处理方法是:

1)记录数组中一共几行几列,有多少个不同的值

2)把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序规模

2、应用实例

1)使用稀疏数组,来保留类似前面的前面的二维数组(棋盘、地图等)

2)把稀疏数组存盘,并且可以重新恢复原来的二维数组数

3)整体思路分析

       1. 二位数组转稀疏数组

       ①遍历原始的二维数组,得到有效数据的个数sum

       ②根据sum可以创建稀疏数组sparseArr[sum+1][3]

            sum+1:第一行表示二维数组的行、列、值

       ③将二维数组的有效个数保存到稀疏数组

       ④将稀疏数组写入到磁盘

     2.将稀疏数组转换成二维数组

        ①从磁盘读取稀疏数组

        ②先读取稀疏数组的第一行,根据第一行,创建原始的二维数组

        ③再读取稀疏数组第一行后面的数据,并赋值给原始的二位数据即可

3、代码如下

package online.zavier.datastructures.sparsearray;

import java.io.*;

/**
 * 稀疏数组
 */
public class Sparsearray {
    //棋盘的行数
    public static final int row = 11;
    //棋盘的列数
    public static final int col = 11;
    //创建保存稀疏数组的文件(当前项目跟路径下)
    File file = new File(System.getProperty("user.dir") + "/file" +  "\\map.data");

    public static void main(String[] args) throws Exception{
        Sparsearray spa = new Sparsearray();
        //获取稀疏数组
        spa.getSparseArr();
        //把稀疏数组还原成二维数组
        spa.restore();
    }

    //获取稀疏数组
    public void getSparseArr() {
        //创建初始二维数组  11 * 11
        int chessArr[][] = new int[row][col];
        // 0表示没有棋子,1 表示白棋,2表示黑棋
        chessArr[2][5] = 2;
        chessArr[5][4] = 1;
        chessArr[5][3] = 1;
        chessArr[6][5] = 2;
        System.out.println("初始数组");
        // 获取非0个数
        int sum = 0;
        for (int[] row : chessArr) {
            for (int data : row) {
                System.out.printf("%d\t", data);
                if (data != 0)
                    sum++;
            }
            System.out.println();
        }
        //创建稀疏数组
        int sparseArr1[][] = new int[sum + 1][3];
        //给稀疏数组赋初始值
        sparseArr1[0][0] = chessArr.length;//行数
        sparseArr1[0][1] = chessArr[1].length;//列数
        sparseArr1[0][2] = sum;//有几个非0的值
        //创建行计数器
        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++;
                    sparseArr1[count][0] = i;
                    sparseArr1[count][1] = j;
                    sparseArr1[count][2] = chessArr[i][j];
                }
            }
        }
        System.out.println("稀疏数组");
        for (int[] row : sparseArr1 ) {
            for (int col : row ) {
                System.out.printf("%d\t", col);
            }
            System.out.println();
        }
        //把棋盘存档,保存在本地磁盘
        download(sparseArr1);
    }

    //把稀疏数组还原成二维数组
    public int[][] restore() throws Exception{
        //读档,获取保存在本地磁盘的稀疏数组
        int[][] sparseArr2 = read();
        //创建还原稀疏数组的二维数组对象
            int[][] chessArr2 = new int[row][col];
            System.out.println("===================从磁盘还原成稀疏数组===================");
            //把稀疏数组还原成二维数组
            for (int i=0;i<sparseArr2.length;i++){
                System.out.printf("%d\t%d\t%d\t\n",sparseArr2[i][0],sparseArr2[i][1],sparseArr2[i][2]);
                if (i!=0)
                chessArr2[sparseArr2[i][0]] [sparseArr2[i][1]]= sparseArr2[i][2];
            }
            System.out.println("===================稀疏数组还原成二位数组===================");
            for (int [] row :chessArr2){
                for (int data:row){
                    System.out.printf("%d\t",data);
                }
                System.out.println();
            }
            return chessArr2;


    }

    //把棋盘存档,保存在本地磁盘
    public void download(int[][]sparseArr1){
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file.getPath());
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8");
            for (int i = 0; i < sparseArr1.length; i++) {
                //把稀疏数组保存到磁盘中
                outputStreamWriter.write(sparseArr1[i][0] + "," + sparseArr1[i][1] + "," + sparseArr1[i][2] + ",");
            }
            //关闭输出流
            outputStreamWriter.close();
            fileOutputStream.close();
            System.out.println("===================把稀疏数组保存到磁盘成功===================");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("===================把稀疏数组保存到磁盘失败===================");
        }
    }

    //读档,从本地磁盘中读取
    public int[][] read() throws Exception {
        if (!file.exists()){
            System.out.println("===================磁盘中不存在map.data文件===================");
            return null;
        }
        System.out.println("===================从磁盘中读取map.data文件===================");
        FileInputStream fileInputStream = new FileInputStream(file);
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"UTF-8");
        StringBuffer stringBuffer = new StringBuffer();
        while (inputStreamReader.ready()){
            stringBuffer.append((char)inputStreamReader.read());
        }
        System.out.println("===================读取成功===================");
        //关闭输入流
        inputStreamReader.close();
        fileInputStream.close();
        //创建一个数组,用来接收稀疏数组保存在磁盘中的值
        String[] sparse = stringBuffer.toString().split(",");
        //创建一个稀疏数组,用来接收之前保存在磁盘中的值
        int[][] sparseArr2 = new int[sparse.length/3][3];
        for (int i =0;i<sparse.length;i++){
            sparseArr2[i/3][i%3] =Integer.valueOf(sparse[i]);
        }
        return sparseArr2;
    }
}

4、结果如下

初始数组
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	2	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	1	1	0	0	0	0	0	0	
0	0	0	0	0	2	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
稀疏数组
11	11	4	
2	5	2	
5	3	1	
5	4	1	
6	5	2	
===================把稀疏数组保存到磁盘成功===================
===================从磁盘中读取map.data文件===================
===================读取成功===================
===================从磁盘还原成稀疏数组===================
11	11	4	
2	5	2	
5	3	1	
5	4	1	
6	5	2	
===================稀疏数组还原成二位数组===================
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	2	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	1	1	0	0	0	0	0	0	
0	0	0	0	0	2	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值