Java | 稀疏數組

數據結構

/*
 * 數據結構包括:線性結構和非線性結構
 *  1. 線性結構:
 *      1.1 線性結構作爲最常用的數據結構,其特點是數據元素之間存在一對一的線性關係
 *      1.2 線性結構有兩種不同的存儲結構,即順序存儲結構(數組)和鏈式存儲結構(鏈表)。
 *          順序存儲的線性表稱爲順序表,順序表中的存儲元素是連續的
 *          鏈式存儲的線性表稱爲鏈表,鏈表中的存儲元素不一定是連續的,元素節點中存放數據元素以及相鄰元素的地址信息
 *      1.3 線性結構常見的有:數組、隊列、鏈表和棧
 *  2. 非線性結構:
 *      非線性結構包括:二維數組、多維數組、廣義表、樹結構和圖結構
*/

稀疏數組

/* 稀疏數組
 *  1. 實際需求:編寫的五子棋程序(使用二維數組記錄棋盤,黑子爲1,白子爲2,無子爲0)中,有存盤退出和續上盤的功能
 *  2. 分析問題:因爲二維數組存在很多值是默認值0,因此記錄了很多沒有意義的數據 ---> 稀疏數組
 *  3. 基本介紹:當一個數組中大部分元素爲0,或者爲同一個值的數組時,可以使用稀疏數組來保存數據
 *  4. 稀疏數組的處理方法:
 *      4.1. 記錄數組一共有幾行幾列,有多少個不同的值
 *      4.2. 把具有不同值的元素的行列及值記錄在一個小規模的數組中,從而縮小程序的規模
 *  5. 應用實例:
 *      5.1. 使用稀疏數組,來保留類似前面的二維數組(棋盤、地圖等等)
 *      5.2. 把稀疏數組存盤,並且可以重新恢復原來的二維數組
 *
 * 二維數組轉稀疏數組:
 *  1. 遍歷原始的二維數組,得到有效數據的個數sum
 *  2. 根據sum就可以創建稀疏數組sparseArr int[sum + 1][3]
 *  3. 將二維數組的有效數據存入到稀疏數組
 *
 * 稀疏數組轉原始的二維數組:
 *  1. 先讀取稀疏數組第一行,根據第一行的數據,創建原始的二維數組
 *  2. 在讀取稀疏數組後幾行的數據,並賦給原始的二維數組即可
 */

二維數組與稀疏數組之間的轉換

@Test
public void toSparse(){
    // 創建一個原始的二維數組 11*11
    // 0:表示沒有棋子 1:黑子 2:白子
    int chessLen = 11;
    int chessArr1[][] = new int[chessLen][chessLen];
    // 當前棋盤佈局
    chessArr1[1][2] = 1;
    chessArr1[2][3] = 2;
    chessArr1[4][5] = 2;
    // 輸出棋盤
    for (int[] row: chessArr1){
        for (int data: row){
            System.out.printf("%d\t", data);
        }
        System.out.println();
    }
    /*
        輸出:
            0	0	0	0	0	0	0	0	0	0	0
            0	0	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	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
            0	0	0	0	0	0	0	0	0	0	0
            0	0	0	0	0	0	0	0	0	0	0
    */
    // 原始數組轉稀疏數組
    // 1. 遍歷原始的二維數組,得到有效數據的個數sum
    int sum = 0;
    for (int[] row: chessArr1){
        for (int data: row){
            if (data != 0){
                sum ++;
            }
        }
    }
    // 2. 根據sum就可以創建稀疏數組sparseArr int[sum + 1][3]
    int[][] sparseArr = new int[sum + 1][3];
    sparseArr[0][0] = chessLen;
    sparseArr[0][1] = chessLen;
    sparseArr[0][2] = sum;
    // 3. 將二維數組的有效數據存入到稀疏數組
    int currentRow = 0; // 當前sparseArr存入第幾個數據
    for (int i = 0; i < chessLen; i++) {
        for (int j = 0; j < chessLen; j++) {
            if (chessArr1[i][j] != 0){
                currentRow ++;
                sparseArr[currentRow][0] = i;
                sparseArr[currentRow][1] = j;
                sparseArr[currentRow][2] = chessArr1[i][j];
            }
        }
    }
    // 輸出稀疏數組
    for (int[] row: sparseArr){
        for (int data: row){
            System.out.printf("%d\t", data);
        }
        System.out.println();
    }
    /*
        輸出:
            11	11	3
            1	2	1
            2	3	2
            4	5	2
         */
    // 稀疏數組轉原始數組
    // 1. 先讀取稀疏數組第一行,根據第一行的數據,創建原始的二維數組
    int arrRowLen = sparseArr[0][0];
    int arrColLen = sparseArr[0][1];
    int dataSum = sparseArr[0][2];
    int[][] chessArr2 = new int[arrRowLen][arrColLen];
    // 2. 在讀取稀疏數組後幾行的數據,並賦給原始的二維數組即可
    for (int i = 1; i <= dataSum; i++) {
        chessArr2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
    }
    // 輸出棋盤
    for (int[] row: chessArr2){
        for (int data: row){
            System.out.printf("%d\t", data);
        }
        System.out.println();
    }
    /*
        輸出:
            0	0	0	0	0	0	0	0	0	0	0
            0	0	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	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
            0	0	0	0	0	0	0	0	0	0	0
            0	0	0	0	0	0	0	0	0	0	0
     */
}

將稀疏數組保存到磁盤上

@Test
public void saveData(){
    // 創建一個原始的二維數組 11*11
    // 0:表示沒有棋子 1:黑子 2:白子
    int chessLen = 11;
    int chessArr1[][] = new int[chessLen][chessLen];
    // 當前棋盤佈局
    chessArr1[1][2] = 1;
    chessArr1[2][3] = 2;
    chessArr1[4][5] = 2;
    // 原始數組轉稀疏數組
    // 1. 遍歷原始的二維數組,得到有效數據的個數sum
    int sum = 0;
    for (int[] row: chessArr1){
        for (int data: row){
            if (data != 0){
                sum ++;
            }
        }
    }
    // 2. 根據sum就可以創建稀疏數組sparseArr int[sum + 1][3]
    int[][] sparseArr = new int[sum + 1][3];
    sparseArr[0][0] = chessLen;
    sparseArr[0][1] = chessLen;
    sparseArr[0][2] = sum;
    // 3. 將二維數組的有效數據存入到稀疏數組
    int currentRow = 0; // 當前sparseArr存入第幾個數據
    for (int i = 0; i < chessLen; i++) {
        for (int j = 0; j < chessLen; j++) {
            if (chessArr1[i][j] != 0){
                currentRow ++;
                sparseArr[currentRow][0] = i;
                sparseArr[currentRow][1] = j;
                sparseArr[currentRow][2] = chessArr1[i][j];
            }
        }
    }
    // 將稀疏數組保存到磁盤上,比如map.dat
    FileWriter fw = null;
    BufferedWriter bw = null;
    try {
        File file = new File("SparseArr.dat");
        fw = new FileWriter(file);
        bw = new BufferedWriter(fw);
        for (int i = 0; i < sparseArr.length; i++) {
            for (int j = 0; j < sparseArr[i].length; j++) {
                bw.write(sparseArr[i][j] + "\t");
            }
            bw.write("\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

恢復原來的數組,讀取sparseArr.dat進行恢復

@Test
public void parseData(){
    // 將稀疏數組保存到磁盤上,比如map.dat
    FileReader fr = null;
    BufferedReader br = null;
    try {
        File file = new File("SparseArr.dat");
        fr = new FileReader(file);
        br = new BufferedReader(fr);
        String str = br.readLine();
        String[] s = str.split("\t");
        // 1. 先讀取稀疏數組第一行,根據第一行的數據,創建原始的二維數組
        int arrRowLen = Integer.parseInt(s[0]);
        int arrColLen = Integer.parseInt(s[1]);
        int dataSum = Integer.parseInt(s[2]);
        int[][] chessArr = new int[arrRowLen][arrColLen];
        str = br.readLine();
        while (str != null){
            s = str.split("\t");
            // 2. 在讀取稀疏數組後幾行的數據,並賦給原始的二維數組即可
            chessArr[Integer.parseInt(s[0])][Integer.parseInt(s[1])] = Integer.parseInt(s[2]);
            str = br.readLine();
        }
        // 輸出棋盤
        for (int[] row: chessArr){
            for (int data: row){
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章