(一)Java資料結構之稀疏陣列

Bug哆哆發表於2020-10-05

稀疏陣列(sparse array)是一種只為陣列中的非零元素分配記憶體的特殊型別陣列,分為三列:

  1. 行下標
  2. 列下標

第一行為總行數、總列數、值的個數,其他行儲存了非零元素的下標和值。

根據上圖我們可以寫出如下程式碼實現稀疏陣列:

package top.baikunlong.sparsearray;

import java.io.*;

/**
 * @author baikunlong
 * @date 2020/10/5 20:38
 * @apiNote
 */
public class SparseArray {
    public static void main(String[] args) {
        //建立原陣列
        int[][] originArray = new int[11][11];
        //賦值
        originArray[1][2] = 1;
        originArray[2][3] = 2;
        int length = originArray.length;
        System.out.println("原陣列:");
        //列印一下原陣列並得到原陣列有效的個數
        int count = 0;
        for (int i = 0; i < length; i++) {
            for (int j = 0; j < length; j++) {
                System.out.print(originArray[i][j] + "  ");
                if (originArray[i][j] != 0) {
                    count++;
                }
            }
            System.out.println();
        }
        System.out.println("有效值個數:" + count);
        //建立稀疏陣列,因為第一行是用來存 行列數 和 值個數(檔案讀取恢復稀疏陣列時會用到這個數) 的,所以要多一行
        int[][] sparseArray = new int[count + 1][3];
        sparseArray[0][0] = length;
        sparseArray[0][1] = length;
        sparseArray[0][2] = count;
        //給稀疏陣列賦值,把原陣列裡非零的值存起來
        int rowIndex=1;//這裡需要一個行下標記錄下當前儲存第幾行,第一行已經存了行列數和值個數,所以從第二行開始存
        for (int i = 0; i < length; i++) {
            for (int j = 0; j < length; j++) {
                if (originArray[i][j] != 0) {
                    sparseArray[rowIndex][0]=i;
                    sparseArray[rowIndex][1]=j;
                    sparseArray[rowIndex][2]=originArray[i][j];
                    rowIndex++;
                }
            }
        }
        System.out.println("稀疏陣列:");
        for (int i = 0; i < sparseArray.length; i++) {
            for (int j = 0; j < sparseArray.length; j++) {
                System.out.print(sparseArray[i][j]+"  ");
            }
            System.out.println();
        }
        //把稀疏矩陣存入檔案SparseArray.data
        final String fileName = "SparseArray.data";
        File file = new File(fileName);
        try(FileOutputStream out = new FileOutputStream(file)) {
            int i = 0;
            for (; i < sparseArray.length-1; i++) {
                out.write((sparseArray[i][0]+"  "+sparseArray[i][1]+"  "+sparseArray[i][2]+"\n").getBytes());
            }
            //最後行不用回車
            out.write((sparseArray[i][0]+"  "+sparseArray[i][1]+"  "+sparseArray[i][0]).getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
        //==========================================================
        //到這裡我們已經把原陣列進行了壓縮,使用稀疏陣列進行儲存,現在要開始讀出來,並恢復成原陣列
        try(BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            //讀取第一行,用於建立稀疏陣列
            String s = reader.readLine();
            String[] strings = s.split("  ");
            //注意,這裡建立大小用到了第一行第三列那個 值個數 這個值,它加一就是行數了,列數固定還是三
            int[][] sparseArrayFromFile = new int[Integer.parseInt(strings[2])+1][3];
            //賦值第一行的資料,包含了行列式數和值個數
            sparseArrayFromFile[0][0]=Integer.parseInt(strings[0]);
            sparseArrayFromFile[0][1]=Integer.parseInt(strings[1]);
            sparseArrayFromFile[0][2]=Integer.parseInt(strings[2]);
            //開始讀取下面的下標和值
            rowIndex=1;//行下標
            while ((s=reader.readLine())!=null){
                strings = s.split("  ");
                sparseArrayFromFile[rowIndex][0]=Integer.parseInt(strings[0]);
                sparseArrayFromFile[rowIndex][1]=Integer.parseInt(strings[1]);
                sparseArrayFromFile[rowIndex][2]=Integer.parseInt(strings[2]);
                rowIndex++;
            }
            //列印檔案讀取出來的稀疏陣列
            System.out.println("列印檔案讀取出來的稀疏陣列:");
            for (int i = 0; i < sparseArrayFromFile.length; i++) {
                for (int j = 0; j < sparseArrayFromFile.length; j++) {
                    System.out.print(sparseArrayFromFile[i][j]+"  ");
                }
                System.out.println();
            }
            //恢復原始陣列
            int[][] recoveredArray = new int[sparseArrayFromFile[0][0]][sparseArrayFromFile[0][1]];
            for (int i = 1; i < sparseArrayFromFile.length; i++) {
                recoveredArray[sparseArrayFromFile[i][0]][sparseArrayFromFile[i][1]]=sparseArrayFromFile[i][2];
            }
            //列印恢復的陣列
            System.out.println("列印恢復的陣列");
            for (int i = 0; i < recoveredArray.length; i++) {
                for (int j = 0; j < recoveredArray.length; j++) {
                    System.out.print(recoveredArray[i][j]+"  ");
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

執行結果如下:

相關文章