稀疏数组的实现

文章介绍了如何使用Java实现二维数组到稀疏数组的转换,以节省内存空间,特别是在处理大量零值的情况,如棋盘数据。详细阐述了稀疏数组的概念和结构,并提供了具体的代码示例,包括将二维数组转换为稀疏数组,将稀疏数组保存到文件,然后从文件读取并恢复为二维数组的过程。
摘要由CSDN通过智能技术生成

稀疏数组的实现

思想

稀疏数组是对二维数组进行简化,假如有一个棋盘,那么对棋盘的数据进行保存就会占很多内存,为了解决这一状况,就是用稀疏数组来简化二维数组。

例如:以0为下棋点,1为黑棋,2为白棋 那么棋盘中有很多没有数据的点(即0),所以保存这样的数据用稀疏数组更合适。
在这里插入图片描述

稀疏数组本质也是二维数组,它将棋盘中有效的数据提取出来,再次使用的时候,将有效数据展示出来就行了

稀疏数组的第一行是个特殊行,从第二行开始,是数据保存的位置。

具体实现

举个例子吧:

		//先创建一个原始的二维数组11*11
        // 0->没有棋子  1->黑子 2->白子
        int chessArr1[][] = new int[11][11];
		//为这个棋盘存放3个棋子
        chessArr1[1][2] = 1;
        chessArr1[2][3] = 2;
        chessArr1[3][4] = 2;

那么,第一行第一个数据保存的就是这个棋盘的行数,即

sparseArr[0][0] = 11;

第一行的第二个数据保存的就是这个棋盘的列数,即

sparseArr[0][1] = 11;

第一行的第三个数据保存的是这个棋盘的有效数据的个数,即

sparseArr[0][2] = 3;

从第二行开始,每行第一个数据保存的是有效数据的所在行,第二个数据保存的是有效数据的所在列,第三个数据保存的是有效数据的值,即

//以第二行为例
sparseArr[1][0] = 1;
sparseArr[1][1] = 2;
sparseArr[1][2] = 1;

以上就是二维数组转稀疏数组的思想了,这样一个棋盘数据就极大的简化了,例如上面那个棋盘的数据转成稀疏数组就成这样的了:
在这里插入图片描述

而将稀疏数组恢复成二维数组也是这样的思想,只不过和上面的步骤反着来的

第一步读取稀疏数组的第一行数据创建一个二维数组

第二步读取稀疏数组的第二行数据对二维数组中所在位置进行赋值

第三步重复第二步操作,直到有效数据填充完毕

以下就是稀疏数组转二维数组的具体实现

		//根据稀疏数组的第一行创建二维数组
        int chessArr2[][] = new int[sparseArr1[0][0]][sparseArr1[0][1]];
        //将稀疏数组中的值写入二维数组中
        for (int j = 1; j <= sparseArr1[0][2]; j++) {
            chessArr2[sparseArr1[j][0]][sparseArr1[j][1]] = sparseArr1[j][2];
        }
        System.out.println("得到的二维数组的形式为~~");
        for (int[] row : chessArr2) {
            for (int data : row) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }

完整代码

为了更好地掌握这一知识点,我们把它转成稀疏数组,然后再保存到文件中,再从文件读出恢复成稀疏数组到转成二维数组。

package com.datestructures.sparsearray;


import java.io.*;

//稀疏数组
public class SparseArray {
    public static void main(String[] args) throws IOException {
        //先创建一个原始的二维数组11*11
        // 0->没有棋子  1->黑子 2->白子
        int chessArr1[][] = new int[11][11];
        chessArr1[1][2] = 1;
        chessArr1[2][3] = 2;
        chessArr1[3][4] = 2;
        //输出原始数组
        System.out.println("原始的二维数组");
        for (int[] row : chessArr1) {
            for (int data : row) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }


        //1.将二维数组转换成稀疏数组
        //先遍历二维数组,统计有多少个非零数据
        int sum = 0;
        for (int i = 0; i < 11; i++) {
            for (int j = 0; j < 11; j++) {
                if (chessArr1[i][j] != 0) {
                    sum++;
                }
            }
        }
        System.out.println("sum=" + sum);


        //2.创建对应的稀疏数组
        int sparseArr[][] = new int[sum + 1][3];
        //给稀疏数组赋值
        sparseArr[0][0] = 11;
        sparseArr[0][1] = 11;
        sparseArr[0][2] = sum;
        //遍历二维数组 将非0数组放到sparseArr中
        int count = 0;//count 用于记录是第几个非零数据
        for (int i = 0; i < 11; i++) {
            for (int j = 0; j < 11; j++) {
                if (chessArr1[i][j] != 0) {
                    count++;
                    sparseArr[count][0] = i;
                    sparseArr[count][1] = j;
                    sparseArr[count][2] = chessArr1[i][j];
                }
            }
        }


        //3.保存稀疏数组到磁盘中
        //地址:E:\资料\尚硅谷Java数据结构和算法\笔记代码课件资料\作业\SparseArray
        //创建一个文件对象
        File file = new File("E:\\资料\\尚硅谷Java数据结构和算法\\笔记代码课件资料\\作业\\SparseArray\\map.txt");
        //用来创建一个文件并向文件中写数据。
        FileOutputStream fos = new FileOutputStream(file);
        //构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,windows上是gbk
        OutputStreamWriter write = new OutputStreamWriter(fos, "UTF-8");
        //输出稀疏数组的形式
        System.out.println();
        System.out.println("得到的稀疏数组的形式为~~");
        for (int i = 0; i < sparseArr.length; i++) {
            System.out.printf("%d\t%d\t%d\t\n", sparseArr[i][0], sparseArr[i][1], sparseArr[i][2]);
            if (i == sparseArr.length - 1) {
                //写入到缓冲区
                write.append(sparseArr[i][0] + "," + sparseArr[i][1] + "," + sparseArr[i][2]);
            } else {
                write.append(sparseArr[i][0] + "," + sparseArr[i][1] + "," + sparseArr[i][2] + ",");
            }
        }
        System.out.println();
        System.out.println("写入文件中...");
        // 关闭写入流,同时会把缓冲区内容写入文件
        write.close();
        // 关闭输出流,释放系统资源
        fos.close();


        //4.根据文件写入稀疏数组
        //向文件中读取数据。
        FileInputStream fip = new FileInputStream(file);
        //构建InputStreamReader对象,编码与写入相同
        InputStreamReader reader = new InputStreamReader(fip, "UTF-8");
        //在使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,
        //所以如果需要对字符串进行修改推荐使用 StringBuffer。
        StringBuffer sb = new StringBuffer();
        //reader.ready()告诉这个流是否准备好被读取。
        // 如果InputStreamReader的输入缓冲区不为空,或者字节可以从底层字节流读取,则InputStreamReader就绪(true)。
        while (reader.ready()) {
            //转成char加到StringBuffer对象中
            sb.append((char)reader.read());
        }
        System.out.println(sb.toString());
        // 关闭读取流
        reader.close();
        // 关闭输入流,释放系统资源
        fip.close();
        将此字符串分割为给定的字符匹配。
        String[] str = sb.toString().split(",");
        // 创建对应的稀疏数组
        int sparseArr1[][] = new int[str.length / 3][3];
        // 给稀疏数组赋值
        int i = 0;
        for (String s : str) {
            sparseArr1[(i - (i % 3)) / 3][i % 3] = Integer.parseInt(s);
            i++;
        }
        System.out.println("读取文件创建的稀疏数组为~~");
        for (int[] row : sparseArr1) {
            for (int data : row) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }


        //5.根据稀疏数组创建二维数组
        //根据稀疏数组的第一行创建二维数组
        int chessArr2[][] = new int[sparseArr1[0][0]][sparseArr1[0][1]];
        //将稀疏数组中的值写入二维数组中
        for (int j = 1; j <= sparseArr1[0][2]; j++) {
            chessArr2[sparseArr1[j][0]][sparseArr1[j][1]] = sparseArr1[j][2];
        }
        System.out.println("得到的二维数组的形式为~~");
        for (int[] row : chessArr2) {
            for (int data : row) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值