c#实现稀疏数组(SparseArray)

tech2024-12-15  7

稀疏数组

基本原理

当一个数组中大部分元素是一个相同元素时,可以使用稀疏数组来保存该数组,从而减少空间占用。

处理方法

1、记录数组一共有几行几列,有多少个不同的值 2、把具有不同值的元素的行数、列数以及值记录在一个小规模的数组中,从而缩小程序规模

样例

在稀疏数组中,第0行的三个数分别代表原始数组的总行数、总列数以及有效值的个数,其余行的数据分别代表有效值所在的行、列以及值。

代码

转换至稀疏数组

static int[,] CompressArray(int[,] originalArr) { //将二维数组转换为稀疏数组 //1.记录有效值个数 int num = 0; //有效值个数 foreach (var item in originalArr) { if (item != 0) { num++; } } int[,] sparseArray = new int[num + 1, 3]; sparseArray[0, 0] = originalArr.GetLength(0); sparseArray[0, 1] = originalArr.GetLength(1); sparseArray[0, 2] = num; //遍历二维数组,将非零值存入稀疏数组 int cnt = 1; //用于记录第几个非零值 for (int i = 0; i < originalArr.GetLength(0); i++) { for (int j = 0; j < originalArr.GetLength(1); j++) { if (originalArr[i, j] != 0) { sparseArray[cnt, 0] = i; sparseArray[cnt, 1] = j; sparseArray[cnt++, 2] = originalArr[i, j]; } } } return sparseArray; }

稀疏数组转换为原始数组

static int[,] RestoreArray(int[,] sparseArray) { /*将稀疏数组恢复为原始数组 * 1.读取稀疏数组第一行,根据第一行的数据创建原始二维数组 * 2.读取稀疏数组后几行数据,并赋给原始数组即可 */ int[,] restoredArr = new int[sparseArray[0, 0], sparseArray[0, 1]]; for (int i = 1; i <= sparseArray.GetLength(1); i++) { restoredArr[sparseArray[i, 0], sparseArray[i, 1]] = sparseArray[i, 2]; } return restoredArr; }

补充程序

实现目标:

1 使用稀疏数组实现对二维数组的压缩 2.将稀疏数组存入文件中 3.读取文件中的稀疏数组 4.将稀疏数组转换回二维数组

代码

using System; using System.IO; namespace SparseArrayExample2 { class Program { static void Main(string[] args) { int[,] originalArr = { {0,0,0,0,0,0,0,0,0,0,0}, {0,0,4,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,6,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, {0,0,6,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,2,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0} }; Console.WriteLine("原始二维数组"); Traverse(originalArr); int[,] sparseArray = CompressArray(originalArr); #region 将稀疏数组写入txt文件 string[] strs = GetStrings(sparseArray); var path = @"..\..\chestInfo"; if (!Directory.Exists(path)) Directory.CreateDirectory(path); path = Path.Combine(path, "info.txt"); var stream = File.Create(path); var writer = new StreamWriter(stream); for (int i = 0; i < strs.Length; i++) { writer.WriteLine(strs[i]); } writer.Flush(); writer.Close(); #endregion #region 读取txt文件中的稀疏数组 var reader = new StreamReader(path); int sum = 0; string nextLine; while ((nextLine = reader.ReadLine()) != null) { sum++; } reader.BaseStream.Seek(0, SeekOrigin.Begin); //返回文件开始处 int[,] sparseArray2 = new int[sum, 3]; for (int i = 0; i < sum; i++) { string[] temStr = (reader.ReadLine()).Split(' '); for (int j = 0; j < temStr.Length; j++) { sparseArray2[i, j] = Convert.ToInt32(temStr[j]); } } reader.Close(); #endregion Wrap(); int[,] restoredArray = RestoreArray(sparseArray2); Traverse(restoredArray); } //打印分割线 static void Wrap() { for (int i = 0; i < 3; i++) Console.WriteLine(); Console.WriteLine("==================================="); } //将数组压缩为稀疏数组 static int[,] CompressArray(int[,] originalArr) { //将二维数组转换为稀疏数组 //1.记录有效值个数 int num = 0; //有效值个数 foreach (var item in originalArr) { if (item != 0) { num++; } } int[,] sparseArray = new int[num + 1, 3]; sparseArray[0, 0] = 11; sparseArray[0, 1] = 11; sparseArray[0, 2] = num; //遍历二维数组,将非零值存入稀疏数组 int cnt = 1; //用于记录第几个非零值 for (int i = 0; i < originalArr.GetLength(0); i++) { for (int j = 0; j < originalArr.GetLength(1); j++) { if (originalArr[i, j] != 0) { sparseArray[cnt, 0] = i; sparseArray[cnt, 1] = j; sparseArray[cnt++, 2] = originalArr[i, j]; } } } return sparseArray; } //解压稀疏数组 static int[,] RestoreArray(int[,] sparseArray) { /*将稀疏数组恢复为原始数组 * 1.读取稀疏数组第一行,根据第一行的数据创建原始二维数组 * 2.读取稀疏数组后几行数据,并赋给原始数组即可 */ int[,] restoredArr = new int[sparseArray[0, 0], sparseArray[0, 1]]; for (int i = 1; i <= sparseArray.GetLength(1); i++) { restoredArr[sparseArray[i, 0], sparseArray[i, 1]] = sparseArray[i, 2]; } return restoredArr; } //遍历二维数组 static void Traverse(int[,] arr) { for (int i = 0; i < arr.GetLength(0); i++) { for (int j = 0; j < arr.GetLength(1); j++) { Console.Write($"{arr[i, j]} "); } Console.WriteLine(); } } //将二维数组转换成字符串数组 static string[] GetStrings(int[,] arr) { string[] str = new string[arr.GetLength(0)]; for (int i = 0; i < arr.GetLength(0); i++) { for (int j = 0; j < arr.GetLength(1); j++) { if (j != arr.GetLength(1) - 1) str[i] += arr[i, j].ToString() + " "; else str[i] += arr[i, j].ToString(); } } return str; } } }
最新回复(0)