稀疏数组如何帮助我们节省内存,提升性能

本文由葡萄城技术团队发布。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。

什么是稀疏矩阵

稀疏矩阵是指矩阵中大部分元素为零的矩阵。在实际应用中,很多矩阵都是稀疏的,比如网络图、文本数据等。由于矩阵中存在大量的零元素,因此稀疏矩阵的存储和计算都具有一定的特殊性。

一般来说,在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。下面的矩阵就是一个典型的稀疏矩阵:

优化稀疏矩阵数据存储的方法

1.直接存储为二维矩阵

使用二维矩阵作为电子表格的存储方法具有简单直接的优点,可以避免频繁地创建或删除内存段。然而,需要指出的是,这种方式在存储值时可能会有一些不太高效的方面,因为它会占用大量的存储空间来保存没有实际内容的单元格。

在实际应用中通常使用三元组表示稀疏矩阵:

三元组的表示方法是:对于一个 m×n 的稀疏矩阵 A,我们只存储矩阵中非零元素的信息,具体来说,将每个非零元素的行下标、列下标和值存储下来,得到一个三元组(i,j,Ai,j),其中 i 是行下标,j 是列下标,Ai,jA 中对应位置的值。

以前面举的稀疏矩阵为例,其三元组表示如下:

(1, 4, 6)
(2, 2, 5)
(3, 3, 4)

直接存储为二维矩阵的复杂度:

  • 占用空间:O(N2)
  • 插入数据:需要破坏矩阵。
  • 删除数据:需要破坏矩阵。
  • 搜索数据:O(N2)。
  • 访问数据:O(1)。

N是假设行和列具有相同长度并形成正方形矩阵的行/列数。

2.通过键值对(Map, Dictionary)优化

通过键值对(Map, Dictionary)来优化,主要是利用哈希表的特性来快速查找元素。具体来说,可以将需要查找的元素作为键,将存储这些元素的数据结构作为值,然后将它们存储在一个哈希表中。这样,当需要查找某个元素时,只需要使用该元素作为键,通过哈希表的查找操作即可快速找到对应的值。

在实际应用中,常见的情况包括:

  1. 缓存数据:在需要频繁访问数据的场景中,通过建立一个缓存,将数据存储在一个键值对的数据结构中,可以显著提高数据的访问效率。
  2. 字符串处理:在需要对字符串进行匹配、查找等操作的场景中,可以将字符串作为键,将相应的处理结果作为值,存储在一个键值对的数据结构中,可以大幅提高字符串处理的效率。
  3. 数据库操作:在需要对数据库进行访问的场景中,可以使用键值对数据结构来存储查询结果,避免重复执行查询操作,减轻数据库的负载。

在下图中,将单元格位置和对应的单元格值以键值对的形式进行了存储。

通过键值对(Map, Dictionary)优化稀疏数组的复杂度:

  • 空间:O(N)。
  • 插入:O(1)。
  • 删除:O(1)。
  • 搜索:O(N)。
  • 访问:O(1)。

N为所记录的条目数。

3.通过数组存储方式优化

在稀疏矩阵中,我们可以使用三个不同的数组来存储行索引、列偏移、和其中的值,而不是直接在二维矩阵中存储值。

存储的三个数组:

  1. =>单元格中的值。
  2. 行索引=>单元格的行索引。
  3. 列偏移=>这里每个索引都代表列,并且该数组将行开始的索引值存储在 Row 数组中。

下图为将稀疏数组转化为数组的形式:

稀疏矩阵具体的插入,删除,搜索,访问的代码:

import java.util.HashMap;
import java.util.Map;

class SparseMatrix {
    private int rows;
    private int cols;
    private Map<String, Integer> matrix;

    public SparseMatrix(int rows, int cols) {
        this.rows = rows;
        this.cols = cols;
        this.matrix = new HashMap<>();
    }

    public void insert(int row, int col, int value) {
        if (row < 0 || row >= rows || col < 0 || col >= cols) {
            throw new IndexOutOfBoundsException("Invalid matrix index");
        }
        if (value != 0) {
            String key = row + "," + col;
            matrix.put(key, value);
        }
    }

    public void delete(int row, int col) {
        String key = row + "," + col;
        matrix.remove(key);
    }

    public int search(int row, int col) {
        String key = row + "," + col;
        return matrix.getOrDefault(key, 0);
    }

    public int access(int row, int col) {
        if (row < 0 || row >= rows || col < 0 || col >= cols) {
            throw new IndexOutOfBoundsException("Invalid matrix index");
        }
        String key = row + "," + col;
        return matrix.getOrDefault(key, 0);
    }
}

在上述代码中,定义了一个 SparseMatrix 类来表示稀疏矩阵。在构造函数中,我们传入矩阵的行数和列数,并创建了一个 HashMap 对象 matrix 来存储非零元素。insert 方法用于向矩阵中插入元素,如果插入的值不为零,则将其加入 matrix 中,其中键为字符串形式的 row,col。delete 方法用于删除指定位置的元素,通过 remove 方法从 matrix 中移除对应的键值对。search 方法用于搜索指定位置的元素,通过调用 getOrDefault 方法从 matrix 中获取对应的值,如果不存在则返回默认值 0。access 方法用于访问指定位置的元素,如果超出矩阵边界则抛出异常,通过调用 getOrDefault 方法从 matrix 中获取对应的值。

通过稀疏矩阵存储方式优化的复杂度:

  • 空间:O(N)。
  • 插入:O(N)。
  • 删除:O(N)。
  • 搜索:O(N)。
  • 访问:O(1)。

总结

相较于传统的数组存储或键值对存储,稀疏矩阵存储采用一种基于行索引的数据字典存储方法,这种方法在处理松散布局的表格数据时表现出色。与其他存储方式不同,稀疏矩阵只存储非空数据,无需额外开辟内存空间来存储空数据。这种特殊存储策略使得数据片段化变得容易,可以随时框取整个数据层中的一片数据进行序列化或反序列化。如果在项目开发中需要存储类似结构的数据,使用稀疏矩阵存储方式能够显著提升性能,无论从时间还是空间上都有很大的优势,葡萄城公司的纯前端表格控件——SpreadJS正是借助此功能实现了高性能渲染能力(100 毫秒内加载 10 万行数据)。

扩展链接:

Redis从入门到实践

一节课带你搞懂数据库事务!

Chrome开发者工具使用教程

从表单驱动到模型驱动,解读低代码开发平台的发展趋势

低代码开发平台是什么?

基于分支的版本管理,帮助低代码从项目交付走向定制化产品开发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/138268.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

线性回归预测波士顿房价 loss为NAN原因 画散点图找特征与标签的关系

波士顿房价csv文件 链接: https://pan.baidu.com/s/1uz6oKs7IeEzHdJkfrpiayg?pwdvufb 提取码: vufb代码 %matplotlib inline import random import torch import matplotlib.pyplot as plt import numpy as np import pandas as pd import torch从CSV中取出数据集 # 加载数…

SAP ABAP列表格式及表格输出

REPORT YTEST001. DATA wa LIKE spfli. WRITE: /. WRITE: 10航班承运人,40航班连接,60国家代码,80起飞城市,100起飞机场. SELECT * INTO wa FROM spfli.WRITE: / wa-carrid UNDER 航班承运人,wa-connid UNDER 航班连接,wa-countryfr UNDER 国家代码,wa-cityfrom UNDER 起飞城市…

保洁行业上门预约小程序源码系统 轻松预约 避免排队 源码开源可二开 带完整部署教程

生活节奏的逐步加快&#xff0c;人们对家庭保洁服务的需求日益增长。为了满足这一需求&#xff0c;我们为您打造了一款保洁行业上门预约小程序源码系统。这款系统让您轻松预约保洁服务&#xff0c;避免排队等待&#xff0c;同时源码开源可进行二次开发&#xff0c;还带有完整的…

详解Python中单引号双引号三引号的用法(适合小白)

单引号和双引号的使用 python 中单引号和双引号都是用来表示字符串&#xff0c;在一般情况下两者没有任何差别&#xff0c;在编码时统一规则即可 str1hello python! str2"hello python!" print(str1) print(str2) 有的时候我们需要在输出的字符串中输出双引号或者…

上课笔记(11.11之前笔记)

一.数据结构的分类 1.数据结构中分为四大类&#xff1a;线性表&#xff0c;哈希表&#xff0c;树&#xff0c;图。 2.线性表&#xff08;line table&#xff09;&#xff1a;呈现线性结构的一种数据结构。具有顺序性&#xff0c;也就是所有数据都是有序的&#xff1b; 数组&…

【无标题】111

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

通讯协议学习之路(实践部分):UART开发实践

通讯协议之路主要分为两部分&#xff0c;第一部分从理论上面讲解各类协议的通讯原理以及通讯格式&#xff0c;第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN&#xff1b;视频会发布在bilibili(UID:399951374) 本文…

Javascript享元模式

Javascript享元模式 1 什么是享元模式2 内部状态与外部状态3 享元模式的通用结构4 文件上传4.1 对象爆炸4.2 享元模式重构 5 没有内部状态的享元模式6 对象池7 通用对象池实现 1 什么是享元模式 享元&#xff08;flyweight&#xff09;模式是一种用于性能优化的模式&#xff0…

数据恢复工具推荐,高效恢复,这4款很实用!

很多电脑用户都会选择将文件直接保存在电脑上&#xff0c;但是在实际的操作过程中&#xff0c;数据丢失的情况难免会出现。而实用的数据恢复工具或许能有效帮助我们找回丢失的数据。电脑上有哪些使用效果比较好的数据恢复工具呢&#xff1f; 今天小编总结了几款好用的工具&…

leetcode:21. 合并两个有序链表

一、题目 函数原型&#xff1a; struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 二、思路 合并两个有序链表为一个新的升序链表&#xff0c;只需要遍历两个有序链表并比较结点值大小&#xff0c;依次将较小的结点尾插到新链表即可。 三、代码…

C#中.NET Framework 4.8控制台应用通过EF访问已建数据库

目录 一、创建.NET Framework 4.8控制台应用 二、建立数据库 1. 在SSMS中建立数据库Blogging 2.在VS上新建数据库连接 三、安装EF程序包 四、自动生成EF模型和上下文 1.Blog.cs类的模型 2.Post.cs类的模型 3.BloggingContext.cs数据库上下文 五、编写应用程序吧 我们…

Vatee万腾数字化引领未来,vatee创新思维

随着数字化时代的全面来临&#xff0c;Vatee万腾正以其独特的创新思维&#xff0c;为未来描绘出令人瞩目的数字化画卷。在这个充满变革和机遇的时代&#xff0c;Vatee万腾所展现的数字化引领力和创新思维&#xff0c;成为业界的翘楚。 Vatee万腾的创新思维贯穿于其数字化战略的…

数据结构 | 队列的实现

数据结构 | 队列的实现 文章目录 数据结构 | 队列的实现队列的概念及结构队列的实现队列的实现头文件&#xff0c;需要实现的接口 Queue.h初始化队列队尾入队列【重点】队头出队列【重点】获取队列头部元素获取队列队尾元素获取队列中有效元素个数检测队列是否为空销毁队列 Que…

更新:扶风解析计费系统V1.8.2源码/免授权优化版+附教程/修正完整版

源码简介&#xff1a; 最新的扶风解析计费系统V1.8.2源码&#xff0c;它是修正完整版&#xff0c;免授权优化版附带了教程。是更新优化版最新 V1.8 版本免授权版本。 之前分享过1.7.1版本的扶风计费系统&#xff0c;该版本已经存在相当长的时间&#xff0c;并且一直没有进行更…

一文读懂:什么是RISC-V?为啥它是国产芯崛起的关键?

各位ICT的小伙伴们大家好呀。 提到CPU&#xff0c; 大家首先就会想到"卡脖子"事件。 X86和ARM的IP授权虽然方便&#xff0c;但是不自主和不可控&#xff0c; 一被限制就可能导致国内一夜间"无芯"可用。 今天我们就来聊聊一个解决芯片卡脖子的有效方式-…

多路复用IO:select、poll、epoll

文章目录 一、常见的IO模型二、什么是多路IO复用&#xff1f;三、select、poll、epollselectpollepoll 四、总结 一、常见的IO模型 概念优点       缺点适用场景阻塞IOBlocking IO当应用程序执行IO操作时&#xff0c;会被阻塞&#xff0c;直到数据准备好或者IO操作完成才…

项目管理工具:提高团队协作效率,确保项目按时完成

项目管理对于企业的成功至关重要&#xff0c;一个好的项目管理工具可以提高团队协作效率&#xff0c;确保项目按时完成&#xff0c;并保持项目进度的高效跟踪。 近年来&#xff0c;一款名为“进度猫”的项目管理工具逐渐崭露头角&#xff0c;它以其独特的功能和优势&#xff…

删除快一年的数据,能够恢复吗?

在数字化时代&#xff0c;数据已经成为了企业和个人生活中不可或缺的一部分。然而&#xff0c;由于各种原因&#xff0c;我们有时会需要删除某些数据&#xff0c;比如过期的文件、无用的照片或者账号下的旧信息等。但是&#xff0c;当我们删除这些数据后&#xff0c;是否真的能…

提高生产效率和质量,这个方式很有效

在当今竞争激烈的市场环境下&#xff0c;企业需要不断提高生产效率和质量水平以保持竞争优势。而精益生产正是一种能够帮助企业实现这一目标的方法。其中&#xff0c;持续改善是精益生产的核心理念之一。它是指通过不断地寻找和消除浪费&#xff0c;改善流程和提高效率来实现质…

PHP中$_SERVER全局变量

在PHP中&#xff0c;$_SERVER 是一个全局数组变量&#xff0c;它包含了有关服务器和当前脚本的信息。$_SERVER 数组中的每个元素都是服务器环境的一个参数&#xff0c;如请求的方法、请求的 URI、客户端 IP 地址等。 PATH 系统环境变量的值&#xff0c;包含了多个目录的路径…