稀疏数组和二维数组相互转化以及在磁盘存取稀疏数组,实现棋盘的存档和复盘

稀疏数组

稀疏数组举例说明

在这里插入图片描述

应用举例

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

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

  3. 整体思路分析如下:

在这里插入图片描述

二维数组转稀疏数组的思路:

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

  2. 根据 sum 就可以创建稀疏数组 sparseArr int [sum+1][3]

  3. 将二维数组的有效数据存入到稀疏数组

稀疏数组转原始的二维数组的思路:

  1. 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的 chessArr2 = int [11][11]
  2. 在读取稀疏数组后几行的数据,并赋给原始的二维数组即可。

代码实现

/**
 * 稀疏数组和二维数组的相互转换
 */
public class SparseArray {
	// 定义原始数组和稀疏数组
    private static int[][] originalArray;
    private static int[][] sparseArr;

    public static void main(String[] args) {
        // 原始数组转稀疏数组
        int[][] sparseArr2 = original2Sparse(originalArray, sparseArr);
        // 稀疏数组转原始数组
        Sparse2original(originalArray, sparseArr2);
    }

    /**
     * 将二维数组转化为稀疏数组方法
     * @param originalArray
     * @param sparseArr
     */
    public static int[][] original2Sparse(int[][] originalArray, int[][] sparseArr){
        /*
          二维数组转稀疏数组的思路:
            1. 遍历原始的二维数组,得到有效数据的个数 sum
            2. 根据 sum 就可以创建稀疏数组 sparseArr int \[sum+1][3]
            3. 将二维数组的有效数据存入到稀疏数组
        */
        // 初始化原始数组
        originalArray = initOriginal(originalArray);
        // 打印原始数组
        System.out.println("这是原始二维数组:");
        for(int i = 0; i < originalArray.length; i++){
            for(int j = 0; j < originalArray[i].length; j++){
                System.out.printf("%d\t", originalArray[i][j]);
            }
            System.out.println();
        }

        // 1. 遍历原始的二维数组,得到有效数据的个数 sum
        int sum = 0;
        for(int i = 0; i < originalArray.length; i++){
            for(int j = 0; j < originalArray[i].length; j++){
                if(originalArray[i][j] != 0){
                    sum++;
                }
            }
        }
        // 2. 根据 sum 就可以创建稀疏数组 sparseArr int[sum+1][3]
        sparseArr = new int[sum+1][3];
        // 3. 将二维数组的有效数据存入到稀疏数组
        initSparse(originalArray, sparseArr, sum);
        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]);
        }

        return sparseArr;
    }
    
    /**
     * 稀疏数组转化为二维数组方法
     * @param originalArray
     * @param sparseArr
     */
    public static void Sparse2original(int[][] originalArray, int[][] sparseArr) {
        /*
          稀疏数组转原始的二维数组的思路:
            1. 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的 chessArr2 = int [11][11]
            2. 在读取稀疏数组后几行的数据,并赋给原始的二维数组即可。
        */
        // 1. 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组
        originalArray = new int[sparseArr[0][0]][sparseArr[0][1]];
        // 2. 在读取稀疏数组后几行的数据,并赋给原始的二维数组即可。
        for(int i = 1; i < sparseArr.length; i++){
            originalArray[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
        }

        System.out.println("这是稀疏数组还原的原始数组:");
        // 遍历还原的数组
        for(int i = 0; i < originalArray.length; i++){
            for(int j = 0; j < originalArray[i].length; j++){
                System.out.printf("%d\t", originalArray[i][j]);
            }
            System.out.println();
        }
    }

    /**
     * 初始化原始数组
     * @param originalArray
     */
    private static int[][] initOriginal(int[][] originalArray) {
        // 准备一个二维数组
        originalArray = new int[11][11];
        for(int i = 0; i < originalArray.length; i++){
            for(int j = 0; j < originalArray[i].length; j++){
                originalArray[i][j] = 0;
            }
        }
        originalArray[1][2] = 1;
        originalArray[2][3] = 2;

        return originalArray;
    }
    
    /**
     * 将二维数组有效数据存入稀疏数组方法
     * @param originalArray
     * @param sparseArr
     */
    private static void initSparse(int[][] originalArray, int[][] sparseArr, int sum) {
        sparseArr[0][0] = originalArray.length;
        sparseArr[0][1] = originalArray[0].length;
        sparseArr[0][2] = sum;
        int count = 1;
        for(int i = 0; i < originalArray.length; i++){
            for(int j = 0; j < originalArray[i].length; j++){
                if(originalArray[i][j] != 0){
                    sparseArr[count][0] = i;
                    sparseArr[count][1] = j;
                    sparseArr[count][2] = originalArray[i][j];
                    count++;
                }
            }
        }
    }
}

在硬盘中存取

在实际应用中,我们往往需要将稀疏数组存储到硬盘上,比如棋盘,要求我们保存上次的对局,并能恢复对局,这就考虑到数据的序列化和反序列化。下面我们就上面的数组例子,学习棋盘即映射为数组保存和恢复的过程,复习Java中文件的操作,整体代码如下。

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 稀疏数组和二维数组的相互转换
 */
public class SparseArray {

    private static int[][] originalArray;
    private static int[][] sparseArr;
    private static final String path = "map.data"; // 文件路径设置为项目路径下

    public static void main(String[] args) {
        int[][] sparseArr2 = original2Sparse(originalArray, sparseArr);
        saveSparse(sparseArr2); // 将稀疏数组保存到文件中
        int[][] sparseArr3 = readSparse(); // 读取文件中的稀疏数组
        Sparse2original(originalArray, sparseArr3);
    }

    /**
     * 将二维数组转化为稀疏数组
     *
     * @param originalArray
     * @param sparseArr
     */
    public static int[][] original2Sparse(int[][] originalArray, int[][] sparseArr) {
        /*
          二维数组转稀疏数组的思路:
            1. 遍历原始的二维数组,得到有效数据的个数 sum
            2. 根据 sum 就可以创建稀疏数组 sparseArr int \[sum+1][3]
            3. 将二维数组的有效数据存入到稀疏数组
        */
        // 初始化原始数组
        originalArray = initOriginal(originalArray);
        // 打印原始数组
        System.out.println("这是原始二维数组:");
        for (int i = 0; i < originalArray.length; i++) {
            for (int j = 0; j < originalArray[i].length; j++) {
                System.out.printf("%d\t", originalArray[i][j]);
            }
            System.out.println();
        }

        // 1. 遍历原始的二维数组,得到有效数据的个数 sum
        int sum = 0;
        for (int i = 0; i < originalArray.length; i++) {
            for (int j = 0; j < originalArray[i].length; j++) {
                if (originalArray[i][j] != 0) {
                    sum++;
                }
            }
        }
        // 2. 根据 sum 就可以创建稀疏数组 sparseArr int[sum+1][3]
        sparseArr = new int[sum + 1][3];
        // 3. 将二维数组的有效数据存入到稀疏数组
        initSparse(originalArray, sparseArr, sum);
        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]);
        }

        return sparseArr;
    }

    /**
     * 稀疏数组转化为二维数组
     *
     * @param originalArray
     * @param sparseArr
     */
    public static void Sparse2original(int[][] originalArray, int[][] sparseArr) {
        /*
          稀疏数组转原始的二维数组的思路:
            1. 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的 chessArr2 = int [11][11]
            2. 在读取稀疏数组后几行的数据,并赋给原始的二维数组即可。
        */
        // 1. 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组
        originalArray = new int[sparseArr[0][0]][sparseArr[0][1]];
        // 2. 在读取稀疏数组后几行的数据,并赋给原始的二维数组即可。
        for (int i = 1; i < sparseArr.length; i++) {
            originalArray[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
        }

        System.out.println("这是稀疏数组还原的原始数组:");
        // 遍历还原的数组
        for (int i = 0; i < originalArray.length; i++) {
            for (int j = 0; j < originalArray[i].length; j++) {
                System.out.printf("%d\t", originalArray[i][j]);
            }
            System.out.println();
        }
    }

    /**
     * 初始化原始数组
     *
     * @param originalArray
     */
    private static int[][] initOriginal(int[][] originalArray) {
        // 准备一个二维数组
        originalArray = new int[11][11];
        for (int i = 0; i < originalArray.length; i++) {
            for (int j = 0; j < originalArray[i].length; j++) {
                originalArray[i][j] = 0;
            }
        }
        originalArray[1][2] = 1;
        originalArray[2][3] = 2;

        return originalArray;
    }

    /**
     * 将二维数组有效数据存入稀疏数组
     *
     * @param originalArray
     * @param sparseArr
     */
    private static void initSparse(int[][] originalArray, int[][] sparseArr, int sum) {
        sparseArr[0][0] = originalArray.length;
        sparseArr[0][1] = originalArray[0].length;
        sparseArr[0][2] = sum;
        int count = 1;
        for (int i = 0; i < originalArray.length; i++) {
            for (int j = 0; j < originalArray[i].length; j++) {
                if (originalArray[i][j] != 0) {
                    sparseArr[count][0] = i;
                    sparseArr[count][1] = j;
                    sparseArr[count][2] = originalArray[i][j];
                    count++;
                }
            }
        }
    }

    /**
     * 将稀疏数组保存到文件中
     *
     * @param sparseArr
     */
    private static void saveSparse(int[][] sparseArr) {
        // 创建字符输出流
        FileWriter fileWriter = null;
        try {
            // 数据写入的路径文件
            File file = new File(path);
            // 文件不存在时新建
            if (!file.exists()) {
                file.createNewFile();
            }
            // 字符输出流赋予对象
            fileWriter = new FileWriter(file);
            // 将数组写入文件中
            for (int i = 0; i < sparseArr.length; i++) {
                // 前两列数据用 "," 隔开
                for (int j = 0; j < 2; j++) {
                    fileWriter.write(sparseArr[i][j] + ",");
                }
                // 最后一列不加 "," 而是换行
                fileWriter.write(sparseArr[i][2] + "\n");
            }
            // 把管道的数据全部刷出来
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // fileWriter不为空时关闭资源
                if (fileWriter != null) {
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 从文件中读取出稀疏数组
     *
     * @return
     */
    private static int[][] readSparse() {
        // 声明文件字符输入流
        FileReader fileReader = null;
        // 声明字符输入缓冲流
        BufferedReader bufferedReader = null;
        // 声明二维数组用于存储读取的结果
        int[][] sparseArr = null;
        try {
            // 指定读取文件路径
            fileReader = new FileReader(new File(path));
            // 通过BufferedReader包装字符输入流
            bufferedReader = new BufferedReader(fileReader);
            // 创建集合用于存储读取的文件的一行一行的数据
            List<String> lineStrs = new ArrayList<>();
            // 存储读取到的一行数据
            String lineStr = null;

            // 一行一行遍历文件的数据
            while((lineStr = bufferedReader.readLine()) != null){
                // 将读取到的行添加到 List中
                lineStrs.add(lineStr);
            }

            // 创建数组
            sparseArr = new int[lineStrs.size()][3]; // 集合的大小,即为数组行数
            // 遍历集合,为数组赋值
            int count = 0;
            for(String str : lineStrs){
                String[] strs = str.split(",");
                sparseArr[count][0] = Integer.valueOf(strs[0]);
                sparseArr[count][1] = Integer.valueOf(strs[1]);
                sparseArr[count][2] = Integer.valueOf(strs[2]);
                count++;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭字符输入流
            try {
                if(fileReader != null){
                    fileReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 关闭字符输入缓冲流
            try {
                if(bufferedReader != null){
                    bufferedReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return sparseArr;
    }
}

结果如下图所示:
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值