HSP——雙向連結串列、稀疏陣列
阿新 • • 發佈:2022-03-15
雙向連結串列
雙向連結串列的基本用法(新增,刪除,修改)和單鏈表的相差不多。雙向連結串列中的節點,多了一個pre,也就是指向前一個節點。具體可以檢視程式碼。
連結:https://pan.baidu.com/s/1qD-4CQYYdpyeDHuUPy_qGg
提取碼:10yl
稀疏陣列
當一個數組中大部分元素為0,或者為同一個值的陣列時,可以使用稀疏陣列來儲存該陣列
稀疏陣列的處理方法
記錄陣列一共有幾行幾列,有多少個不同的值 。
把具有不同值的元素的行列及值記錄在一個小規模的陣列中,從而縮小程式的規模.
稀疏陣列列數只有3列。行數為原始二維陣列的有效資料個數+1。
稀疏陣列舉例說明
轉化思路
二維陣列 轉 稀疏陣列的思路
1.遍歷二維陣列,得到有效資料的個數sum。
2.根據sum可以建立稀疏陣列sparseArray in[sum+1][3]
3.將二維陣列的有效資料存入到稀疏陣列。
稀疏陣列 轉 原始的二維陣列
1.先讀取稀疏陣列的第一行,根據第一行的資料,能夠得到原始二維陣列的大小和其中的有效資料的個數。
2.再讀取稀疏陣列的下面幾行資料,並根據位置賦值給原始二維陣列。
程式碼實現
public class SparseArray { public static void main(String[] args) { //建立一個原始的二維陣列 11*11 //0:表示沒有棋子,1:表示黑子,2:表示白子 int chessArray1[][] = new int[11][11]; chessArray1[1][2] = 1; chessArray1[2][3] = 2; //輸出原始的二維陣列 System.out.println("原始的二維陣列--->"); for (int[] row : chessArray1) { for (int data : row) { System.out.printf("%d\t", data); } System.out.println(); } //將二維陣列轉化為稀疏陣列 //1.先遍歷二維陣列,得到非0的資料的個數 int sum = 0; for (int i = 0; i < 11; i++) { for (int j = 0; j < 11; j++) { if (chessArray1[i][j] != 0) { sum++; } } } //2.建立對應的稀疏陣列 int sparseArray[][] = new int[sum + 1][3]; //給稀疏陣列賦值 sparseArray[0][0] = 11; sparseArray[0][1] = 11; sparseArray[0][2] = sum; //遍歷二維陣列,將非0的值存放到sparseArray稀疏陣列中 int count = 0; for (int i = 0; i < 11; i++) { for (int j = 0; j < 11; j++) { if (chessArray1[i][j] != 0) { count++; sparseArray[count][0] = i; sparseArray[count][1] = j; sparseArray[count][2] = chessArray1[i][j]; } } } //輸出稀疏陣列的形式 System.out.println(); System.out.println("稀疏陣列--->"); for (int i = 0; i < sparseArray.length; i++) { System.out.printf("%d\t%d\t%d\n", sparseArray[i][0], sparseArray[i][1], sparseArray[i][2]); } //將稀疏陣列恢復成原始二維陣列 //1.先讀取稀疏陣列的第一行,根據第一行的資料建立原始的二維陣列 int chessArray2[][] = new int[sparseArray[0][0]][sparseArray[0][1]]; //2.在讀取稀疏陣列後幾行的資料(從第二行開始),並賦值給原始的二維陣列 for (int i = 1; i < sparseArray.length; i++) { chessArray2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2]; } //輸出恢復後的陣列 System.out.println(); System.out.println("恢復後的陣列--->"); for (int[] row : chessArray2) { for (int data : row) { System.out.printf("%d\t", data); } System.out.println(); } } }
要求:
1) 在前面的基礎上,將稀疏陣列儲存到磁碟上,比如 map.data
2) 恢復原來的陣列時,讀取 map.data 進行恢復
System.out.println("-------------------------------------------------------------"); System.out.println("-------------------------------------------------------------"); File file = new File( "F:\\Code\\Java_Code\\structures-algorithms\\data\\src\\sparsearray\\map.data"); //將稀疏陣列寫入到磁碟中的map.data try { FileOutputStream fos = new FileOutputStream(file); OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); BufferedWriter bw = new BufferedWriter(osw); System.out.println("寫入磁碟中···"); for (int i = 0; i < sparseArray.length; i++) { bw.write(sparseArray[i][0] + "," + sparseArray[i][1] + "," + sparseArray[i][2] + ","); } bw.close(); osw.close(); fos.close(); System.out.println("寫入成功"); } catch (IOException e) { e.printStackTrace(); } //讀取磁碟中的map.data,恢復稀疏陣列。 try { System.out.println("讀取中···"); FileInputStream fis = new FileInputStream(file);//讀取檔案的資料到位元組流inputStream InputStreamReader isr = new InputStreamReader(fis, "UTF-8");//將位元組流inputStream轉換成字元流inputStreamReader StringBuffer sb = new StringBuffer(); while (isr.ready()) { //read()返回的是讀取到的位元組 sb.append((char) isr.read()); } isr.close(); fis.close(); System.out.println("讀取成功"); String ss = sb.toString(); System.out.println("從磁碟中讀取的字串為:" + ss); System.out.println(); String[] str = sb.toString().split(","); //恢復稀疏陣列 int[][] sparseArray2 = new int[str.length / 3][3]; //給稀疏陣列賦值 int i = 0; for (String s : str) { sparseArray2[i / 3][i % 3] = Integer.parseInt(s); i++; } //輸出還原後的稀疏陣列 System.out.println("還原後的稀疏陣列-->"); for (int[] sa2 : sparseArray2) { for (int data : sa2) { System.out.printf("%d\t", data); } System.out.println(); } System.out.println(); //再恢復成二維陣列 int array[][] = new int[sparseArray2[0][0]][sparseArray2[0][1]]; //賦值給原始二維陣列 for (i = 1; i < sparseArray2.length; i++) { array[sparseArray2[i][0]][sparseArray2[i][1]] = sparseArray2[i][2]; } System.out.println("恢復成二維陣列-->"); for (int[] row : array){ for (int data:row){ System.out.printf("%d\t",data); } System.out.println(); } } catch (IOException e) { e.printStackTrace(); }
我實驗中的問題
fileOutputStream、outputStreamWriter和bufferedWriter
FileOutputStream fileOutputStream = new FileOutputStream("d:/text.txt");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"MS936");
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
如果只用FileOutputStream fileOutputStream = new FileOutputStream("d:/text.txt");
不是也能輸出到"d:/text.txt"嗎?
為什麼要用其它兩個呢?能起到什麼作用呢?
FileOutputStream 是位元組流,它一個位元組一個位元組的向外邊送資料。
OutputStreamWrite 是字元流,它一個字元一個字元的向外邊送資料。
它們有什麼區別麼?
解析:
因為英文字元佔一個位元組,而中文是一個字元,佔倆位元組。
如果用stream,你讀出來的英語再倒也罷了,讀出來的中文可就是亂碼或者一個個“????”。
如果用WRITER,就不會有亂碼了。
BufferedWriter Buffer是一個緩衝區,為什麼要用BUFFER呢?
如果你直接用stream或者writer,你的硬碟可能就是一個字元或者一個位元組讀寫硬碟一次,可是你用了Buffer, 你的硬碟就是讀了一堆資料之後,讀寫一下硬碟。這樣對你硬碟有好處。
StringBuffer()的基本使用
-
StringBuffer: 執行緒安全的可變字串
- 我們如果對字串進行拼接操作,每次拼接都會構成一個新的String物件,既耗時,又浪費空間
- StringBuffer可以解決這個問題。
- StringBuffer和String的區別?前者長度和內容可變,後者不可變
-
StringBuffer的新增功能
- public StringBuffer append(String str)
- 可以把任意型別資料新增到字串緩衝區裡面,並返回字串緩衝區本身
- public StringBuffer insert(int offset,String str)
- 在指定位置把任意型別的資料插入到字串緩衝區裡面,並返回字串緩衝區本身
- public StringBuffer append(String str)
- StringBuffer其他使用