数组 – 稀疏数组

一,稀疏数组1.定义稀疏数组可以看做是普通数组的压缩,但是这里说的普通数组是值无效数据量远大于有效数据量的数组形如:00000000000001000000000000200000000000000…

大家好,又见面了,我是你们的朋友全栈君。

一,稀疏数组

1.定义

稀疏数组可以看做是普通数组的压缩,但是这里说的普通数组是值无效数据量远大于有效数据量的数组

形如:

              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 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 0
              0 0 0 0 0 0 0 0 0 0 0
              0 0 0 0 0 0 0 0 0 0 0

其稀疏数组形式:

              11 11 2
              1  2  1
              2  4  2

2.存储

刚说到稀疏数组是一种压缩后的数组,为什么要进行压缩存储呢?

  • 原数组中存在大量的无效数据,占据了大量的存储空间,真正有用的数据却少之又少

  • 压缩存储可以节省存储空间以避免资源的不必要的浪费,在数据序列化到磁盘时,压缩存储可以提高IO效率

3.存储方式

1.普通存储

第一行存储原始数据总行数,总列数,总的非0数据个数

接下来每一行都存储非0数所在行,所在列,和具体值

形如:

    rows cols n
    r1   c1   val1
    r2   c2   val2
    .    .     .
    .    .     .
    rn   cn   valn

eg :

              11 11 2
              1  2  1
              2  4  2

2.链式存储

以这个为例:

        0 0 0 0 
        0 1 0 0
        0 0 2 0
        0 0 3 0

a.普通链式存储

# 一,稀疏数组

b.行式链式存储

在这里插入图片描述

c.十字链式存储

在这里插入图片描述

4.代码实现

/** * @Description: 稀疏数组 ---> 数组中有很多无效数据,压缩数组 * @Author: Kevin * @CreateDate: 2019/7/2 22:39 * @UpdateUser: Kevin * @UpdateDate: 2019/7/2 22:39 * @UpdateRemark: 修改内容 * @Version: 1.0 */
public class SparseArray { 
   

    /** * <p> * 稀疏数组可以简单的看作为是压缩,在开发中也会使用到。比如将数据序列化到磁盘上,减少数据量,在IO过程中提高效率等等。 * * <p> * 为什么要进行压缩? * - 由于稀疏矩阵中存在大量的“空”值,占据了大量的存储空间,而真正有用的数据却少之又少, * - 且在计算时浪费资源,所以要进行压缩存储以节省存储空间和计算方便。 * </p> * * </p> * @param args */

    public static void main(String[] args) { 
   

        /** * 初始化二维数组 * <p> * 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 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 0 * 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 * </p> */
        //初始化原数组
        int[][] array = new int[11][11];
        array[1][2] = 1;
        array[2][4] = 2;
        for(int[] row : array){ 
   
            for(int item : row){ 
   
                System.out.printf("%d\t",item);
            }
        }

        System.out.println("---------> 二维数组转稀疏数组");

        /** * 稀疏数组 * <p> * 11 11 2 * 1 2 1 * 2 4 2 * </p> */
        //得到非0数据数
        int sum = 0;
        for (int i = 0;i<11;i++){ 
   
            for(int j = 0;j<11;j++){ 
   
                if(array[i][j] != 0){ 
   
                    sum++;
                }
            }
        }
        //创建稀疏数组
        int[][] sparseArray = new int[sum+1][3];
        //给稀疏数组赋值
        sparseArray[0][0] = 11;
        sparseArray[0][1] = 11;
        sparseArray[0][2] = sum;
        //将非0的数放入稀疏数组
        //count:标识第几个非0数
        int count = 0;
        for (int i = 0;i<11;i++){ 
   
            for(int j = 0;j<11;j++){ 
   
                if(array[i][j] != 0){ 
   
                    count++;
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = array[i][j];
                }
            }
        }
        //遍历稀疏数组
        for(int i = 0;i<sparseArray.length;i++){ 
   
            System.out.printf("%d%d%d\t",sparseArray[i][0],sparseArray[i][1],sparseArray[i][2]);
        }

        System.out.println("----------->稀疏数组转回原始数组");

        /** * 恢复的二维数组 * <p> * 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 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 0 * 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 * </p> */

        int[][] oldArray = new int[sparseArray[0][0]][sparseArray[0][1]];
        //将原来非0的数填充回去
        for(int i = 1;i<=count;i++){ 
   
          oldArray[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        }
        //遍历刚转回的原始数组
        for(int[] row : oldArray){ 
   
            for(int item : row){ 
   
                System.out.printf("%d\t",item);
            }
        }
    }
}

3.将稀疏数组存到此磁盘中

我们可以使用java的IO流将稀疏数组存放到磁盘中,原数组和稀疏数组比较,肯定是稀疏数组体积更小,占用空间更小

        /** * 将稀疏数组存入磁盘(文件) * */
        public static void sparseArrayToIo(int[][] sparseArray) throws Exception { 
   
            File file = new File("sparseArray.txt");
            if(!file.exists()){ 
   
                file.createNewFile();
            }
            FileWriter writer = new FileWriter(file);
            for(int i =0; i < sparseArray.length; i++) { 
   
                for(int j = 0; j < 3; j++) { 
   
                    writer.write(sparseArray[i][j]);
                }
            }
            writer.flush();
            writer.close();
        }

4.从磁盘中读取稀疏数组

在这里有个缺陷就是我不能动态的知道稀疏数组一共有几行,所以我选择传参的方式,这样其实是不太友好的

        /** * 读文件获取稀疏数组(获取指定行数的稀疏数组)【不足】 * @return */
        public static int[][] sparseArrayFromIo(int lineNums) throws Exception { 
   

            FileReader reader = new FileReader("sparseArray.txt");
            int getNum = 0;
            int[][] sparseArray = new int[lineNums][3];
            for(int i = 0;i < lineNums;i++) { 
   
                for (int j = 0; j < 3; j++) { 
   
                    getNum = reader.read();
                    sparseArray[i][j] = getNum;
                }
            }
            return sparseArray;
        }

恢复原数组

            System.out.println("----------->稀疏数组转回原始数组");
            //读取磁盘中的稀疏数组
            try { 
   
                int[][] sparseArrayFromIo = sparseArrayFromIo(3);
                int[][] newOldArray = new int[sparseArrayFromIo[0][0]][sparseArrayFromIo[0][1]];
                //将原来非0的数填充回去
                for(int i = 1;i<=count;i++){ 
   
                    newOldArray[sparseArrayFromIo[i][0]][sparseArrayFromIo[i][1]] = sparseArrayFromIo[i][2];
                }
                //遍历刚转回的原始数组
                for(int[] row : newOldArray){ 
   
                    for(int item : row){ 
   
                        System.out.printf("%d\t",item);
                    }
                }
            } catch (Exception e) { 
   
                e.printStackTrace();
            }

5.完整代码

public class SparseArray { 
   

        /** * <p> * 稀疏数组可以简单的看作为是压缩,在开发中也会使用到。比如将数据序列化到磁盘上,减少数据量,在IO过程中提高效率等等。 * * <h> * 为什么要进行压缩? * - 由于稀疏矩阵中存在大量的“空”值,占据了大量的存储空间,而真正有用的数据却少之又少, * - 且在计算时浪费资源,所以要进行压缩存储以节省存储空间和计算方便。 * </h> * * </p> * @param args */

        public static void main(String[] args) { 
   

            /** * 初始化二维数组 * <p> * 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 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 0 * 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 * </p> */
            //初始化原数组
            int[][] array = new int[11][11];
            array[1][2] = 1;
            array[2][4] = 2;
            for(int[] row : array){ 
   
                for(int item : row){ 
   
                    System.out.printf("%d\t",item);
                }
            }

            System.out.println("---------> 二维数组转稀疏数组");

            /** * 稀疏数组 * <p> * 11 11 2 * 1 2 1 * 2 4 2 * </p> */
            //得到非0数据数
            int sum = 0;
            for (int i = 0;i<11;i++){ 
   
                for(int j = 0;j<11;j++){ 
   
                    if(array[i][j] != 0){ 
   
                        sum++;
                    }
                }
            }
            //创建稀疏数组
            int[][] sparseArray = new int[sum+1][3];
            //给稀疏数组赋值
            sparseArray[0][0] = 11;
            sparseArray[0][1] = 11;
            sparseArray[0][2] = sum;
            //将非0的数放入稀疏数组
            //count:标识第几个非0数
            int count = 0;
            for (int i = 0;i<11;i++){ 
   
                for(int j = 0;j<11;j++){ 
   
                    if(array[i][j] != 0){ 
   
                        count++;
                        sparseArray[count][0] = i;
                        sparseArray[count][1] = j;
                        sparseArray[count][2] = array[i][j];
                    }
                }
            }
            //遍历稀疏数组
            for(int i = 0;i<sparseArray.length;i++){ 
   
                System.out.printf("%d%d%d\t",sparseArray[i][0],sparseArray[i][1],sparseArray[i][2]);
            }
            try { 
   
                //将稀疏数组写入文件
                sparseArrayToIo(sparseArray);
            } catch (Exception e) { 
   
                e.printStackTrace();
            }
            System.out.println("----------->稀疏数组转回原始数组");
            /** * 恢复的二维数组 * <p> * 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 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 0 * 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 * </p> */
            int[][] oldArray = new int[sparseArray[0][0]][sparseArray[0][1]];
            //将原来非0的数填充回去
            for(int i = 1;i<=count;i++){ 
   
              oldArray[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
            }
            //遍历刚转回的原始数组
            for(int[] row : oldArray){ 
   
                for(int item : row){ 
   
                    System.out.printf("%d\t",item);
                }
            }
            System.out.println("----------->稀疏数组转回原始数组");
            //读取磁盘中的稀疏数组
            try { 
   
                int[][] sparseArrayFromIo = sparseArrayFromIo(3);
                int[][] newOldArray = new int[sparseArrayFromIo[0][0]][sparseArrayFromIo[0][1]];
                //将原来非0的数填充回去
                for(int i = 1;i<=count;i++){ 
   
                    newOldArray[sparseArrayFromIo[i][0]][sparseArrayFromIo[i][1]] = sparseArrayFromIo[i][2];
                }
                //遍历刚转回的原始数组
                for(int[] row : newOldArray){ 
   
                    for(int item : row){ 
   
                        System.out.printf("%d\t",item);
                    }
                }
            } catch (Exception e) { 
   
                e.printStackTrace();
            }
        }

        /** * 将稀疏数组存入磁盘(文件) * */
        public static void sparseArrayToIo(int[][] sparseArray) throws Exception { 
   
            File file = new File("sparseArray.txt");
            if(!file.exists()){ 
   
                file.createNewFile();
            }
            FileWriter writer = new FileWriter(file);
            for(int i =0; i < sparseArray.length; i++) { 
   
                for(int j = 0; j < 3; j++) { 
   
                    writer.write(sparseArray[i][j]);
                }
            }
            writer.flush();
        }

        /** * 读文件获取稀疏数组(获取指定行数的稀疏数组)【不足】 * @return */
        public static int[][] sparseArrayFromIo(int lineNums) throws Exception { 
   

            FileReader reader = new FileReader("sparseArray.txt");
            int getNum = 0;
            int[][] sparseArray = new int[lineNums][3];
            for(int i = 0;i < lineNums;i++) { 
   
                for (int j = 0; j < 3; j++) { 
   
                    getNum = reader.read();
                    sparseArray[i][j] = getNum;
                }
            }
            return sparseArray;
        }

}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/125468.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • layui实现iframe框架_layui table重新渲染

    layui实现iframe框架_layui table重新渲染layuiAdmin.std(iframe版)是完全基于layui架构而成的通用型后台管理模板系统,采用传统的iframe多页面开发模式,可更快速直接地开发网页后台应用程序,无需过多地学习成本,简单高效,撸起袖子直接干。题外该文档适用于layuiAdmin.std常规版(iframe),阅读之前请务必确认是否与你使用的版本对应。熟练掌握layuiAdmin的前提是熟练…

    2025年7月8日
    3
  • dfs是什么意思_英语单词搜索软件

    dfs是什么意思_英语单词搜索软件给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words,找出所有同时在二维网格和字典中出现的单词。单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。示例 1:输入:board = [[“o”,”a”,”a”,”n”],[“e”,”t”,”a”,”e”],[“i”,”h”,”k”,”r”],[“i”,”f”,”l”,”v”]], words = [“oath”,

    2022年8月8日
    5
  • 唯一索引和普通索引的区别

    唯一索引和普通索引的区别一、背景介绍索引用来快速地寻找那些具有特定值的记录,如果没有索引,执行查询时Mysql必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录,表里面的记录数量越多,这个操作的代价就越高,如果作为搜索条件的列上已经创建了索引,mysql无需扫描任何记录即可迅速得到目标记录所在的位置。如果表有一千个记录,通过索引查找记录至少要比顺序扫描记录快100倍。所以对于现在的各种大型数据库来说,索…

    2022年9月19日
    5
  • 用了vue还需要jquery吗_vue与react的区别

    用了vue还需要jquery吗_vue与react的区别⾸先呢jquery他是⽤js封装的⼀个类库,主要是为了⽅便操作dom元素,⽽vue他是⼀个框架,并且呢,他会从真实dom构建出⼀个虚拟的dom树,通过di!算法渲染只发⽣改变的dom元素,其他的相同的dom元素不⽤在重新渲染.⽽使⽤jquery去改变dom元素的时候,即使有相同的dom元素也会重新渲染,jq重点操作dom,而vue重点操作数据。以上就是我对vue和jquery区别的理解….

    2022年10月15日
    2
  • pycharm关闭自动补全_python opencv 教程

    pycharm关闭自动补全_python opencv 教程我刚下载pycharm,准备学opencv,然后在网上博客上找了许多文章看了,有的说下载后导入修改cv2文件夹里的_init_.py,但是经过测试也不行,个人感觉总是少了啥,然后找了许多文章看了然后也试了,除了安装opencv成功之外就没有了。后来看了许多文章之后看见每个博客写的方法都不一样,这里我就有点顿悟了…我看到cv2文件夹中的_init_.py里面的code已经说清楚啦,我是刚开始不怎么看得懂英文的意思,后来仔细看了才大概明白了一丢丢…请看:importimportlibimport

    2022年8月26日
    5
  • vagrant共享目录出现“mount:unknown filesystem type ‘vboxsf‘”错误解决方法(亲测可行)

    vagrant共享目录出现“mount:unknown filesystem type ‘vboxsf‘”错误解决方法(亲测可行)

    2022年2月19日
    51

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号