c#实现稀疏数组(SparseArray)

稀疏数组

基本原理

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

处理方法

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;
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值