数据结构与算法:稀疏数组
前言
- 此文以整型元素的二维数组为例,阐述稀疏数组的思想。
- 其他类型或许有更适合压缩算法或者其他结构的稀疏数组,此文暂不扩展。
稀疏数组的定义
在一个二维数据数组里,由于大量的元素的值为同一个值,比如 0或者其他已知的默认值,在处理此类数据的数据的时候,为了某种目的(如节省存储空间)而将 0 值或默认剔除方式,使用一个新数组来组织的剩余数据(此文称为存储有效数据,简称有效数),此时将该新数组称为稀疏数组。
简而言之,存储原二维数组中有效数据信息的数组称为稀疏数组。
如下图中的 0 值是最多的元素,可以将 0 值视为要剔除储存的值,此文称为 剔除数。

此处是压缩思想在数组上的应用,稀疏数组一般用于数据的压缩存储,已达到节省空间的目的。
稀疏数组的结构
二维数据的元素是数值
稀疏数据一般为 N*3的矩阵,N 为非剔除数据的个数,行列式的第一行描述元素的结构信息,如行列数,有效数的个数;其他行描述有效数的具体信息,如所在原数组中的位置。
| 第一列 | 第二列 | 第三列 |
|---|---|---|
| 行号 | 列号 | 值 |
- 第1行,第1列为原始数据的行数
- 第1行,第2列为原始数据的列数
- 第1行,第3列为原始数据的有效数的个数 n ,这个决定了稀疏数组的行数N( N= n+1)
| 第1行(原数组结构信息) | 18(原数组的行数) | 18(原数组的列数) | 68(原数组中有效数的个数) |
|---|---|---|---|
| 第2行(原数组中元素的信息) | 0(值所在的行) | 0(值所在的列) | 7(值为 7) |
二维数据的元素是字符
稀疏数据一般为 N*3的矩阵,N 为非剔除数据的个数
- 第1行,第1列为原始数据的行数
- 第1行,第2列为原始数据的列数
- 第1行,第3列为原始数据的有效数的个数 n ,这个决定了稀疏数组的行数N( N= n+1)
稀疏数组的应用场景
- 数据元素中存在相同值较多且需要存储的情况。
- 网络数据传输的时候,可以根据传输的数据结构,采用稀疏数据的思想
总之,就是可以压缩存储或者压缩传输的时候,都可以考虑此稀疏思想。
案例
该案例演示了一个二维数组(业务数组)和与其匹配的稀疏数组(存储数组),仅为演示二者相互转换,未考虑转换中涉及到的算法优化,仅仅展示存储优化的设计思想。
- 原始数组大小为:18*18=324
- 稀疏数组大小为:68*3=204
转换后节省了 (324-204)/324*100%=37%的空间
package com.jj;import org.junit.jupiter.api.Test;public class TestAlgArray {@Testpublic void test() {int countRow = 18;int countCol = 18;int[][] arr = new int[countRow][countCol];for (int i = 0; i < countCol; i++) {arr[0][i] = 8;arr[7][i] = 5;arr[i][0] = 7;arr[i][7] = 3;}//输出int valueCount = 0;for (int i = 0; i < countCol; i++) {for (int j = 0; j < countCol; j++) {System.out.print(arr[i][j] + " ");if (arr[i][j] != 0) {valueCount++;}}System.out.println();}System.out.println("valueCount:" + valueCount);//生成一个稀疏数组int[][] saveData = new int[valueCount + 1][3];saveData[0][0] = countRow;saveData[0][1] = countCol;saveData[0][2] = valueCount;int index = 1;for (int i = 0; i < countCol; i++) {for (int j = 0; j < countCol; j++) {if (arr[i][j] != 0) {saveData[index][0] = i;saveData[index][1] = j;saveData[index][2] = arr[i][j];index++;}}}//输出 saveDatafor (int i = 0; i < saveData.length; i++) {for (int j = 0; j < saveData[i].length; j++) {System.out.print(saveData[i][j] + " ");}System.out.println();}//恢复业务数组int[][] newArr = new int[saveData[0][0]][saveData[0][1]];for (int i = 1; i < saveData.length; i++) {newArr[saveData[i][0]][saveData[i][1]] = saveData[i][2];}//输出业务数组for (int i = 0; i < newArr.length; i++) {for (int j = 0; j < newArr[i].length; j++) {
// System.out.print(newArr[i][j] + " ");if (newArr[i][j] == 0) {System.out.print(" ");} else {System.out.print(newArr[i][j] + " ");}}System.out.println();}}
}
- 原始数组(业务数据):18x18的矩阵
7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 5 5 5 5 5 5 3 5 5 5 5 5 5 5 5 5 5
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
- 稀疏数组(存储数据):68x3 的矩阵
18 18 68
0 0 7
0 1 8
0 2 8
0 3 8
0 4 8
0 5 8
0 6 8
0 7 8
0 8 8
0 9 8
0 10 8
0 11 8
0 12 8
0 13 8
0 14 8
0 15 8
0 16 8
0 17 8
1 0 7
1 7 3
2 0 7
2 7 3
3 0 7
3 7 3
4 0 7
4 7 3
5 0 7
5 7 3
6 0 7
6 7 3
7 0 7
7 1 5
7 2 5
7 3 5
7 4 5
7 5 5
7 6 5
7 7 3
7 8 5
7 9 5
7 10 5
7 11 5
7 12 5
7 13 5
7 14 5
7 15 5
7 16 5
7 17 5
8 0 7
8 7 3
9 0 7
9 7 3
10 0 7
10 7 3
11 0 7
11 7 3
12 0 7
12 7 3
13 0 7
13 7 3
14 0 7
14 7 3
15 0 7
15 7 3
16 0 7
16 7 3
17 0 7
17 7 3
- 数据恢复
7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 5 5 5 5 5 5 3 5 5 5 5 5 5 5 5 5 5
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0
相关文章:
数据结构与算法:稀疏数组
前言 此文以整型元素的二维数组为例,阐述稀疏数组的思想。其他类型或许有更适合压缩算法或者其他结构的稀疏数组,此文暂不扩展。 稀疏数组的定义 在一个二维数据数组里,由于大量的元素的值为同一个值,比如 0或者其他已知的默认值…...
Meta重磅发布Llama 3.3 70B:开源AI模型的新里程碑
在人工智能领域,Meta的最新动作再次引起了全球的关注。今天,我们见证了Meta发布的Llama 3.3 70B模型,这是一个开源的人工智能模型,它不仅令人印象深刻,而且在性能上达到了一个新的高度。 一,技术突破&#…...
VSCode中的Black Formatter没有生效的解决办法
说明 如果正常按照配置进行的话,理论上是可以生效的。 "[python]": {"editor.defaultFormatter": "ms-python.black-formatter","editor.formatOnSave": true }但我在一种情况下发现不能生效,应为其本身的bug…...
【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题
目录 背包问题简介 问题描述 输入: 输出: 动态规划解法 动态规划状态转移 代码实现 代码解释 动态规划的时间复杂度 例子解析 输出: 总结 作者我蓝桥杯:2023第十四届蓝桥杯国赛C/C大学B组一等奖,所以请听我…...
Odoo:免费开源ERP的AI技术赋能出海企业电子商务应用介绍
概述 伴随电子商务的持续演进,客户对于便利性、速度以及个性化服务的期许急剧攀升。企业务必要探寻创新之途径,以强化自身运营,并优化购物体验。达成此目标的最为行之有效的方式之一,便是将 AI 呼叫助手融入您的电子商务平台。我们…...
微信小程序苹果手机自带的数字键盘老是弹出收起,影响用户体验,100%解决
文章目录 1、index.wxml2、index.js3、index.wxss1、index.wxml <!--index.wxml--> <view class="container"><view class="code-input-container"><view class="code-input-boxes"><!-- <block wx:for="{{…...
sql中case when若条件重复 执行的顺序
sql case when若条件重复 执行的顺序 在 SQL 中,如果你在 CASE 表达式中定义了多个 WHEN 子句,并且这些条件有重叠,那么 CASE 表达式的执行顺序遵循以下规则: (1)从上到下:SQL 引擎会按照 CASE …...
压力测试Jmeter简介
前提条件:要安装JDK 若不需要了解,请直接定位到左侧目录的安装环节。 1.引言 在现代软件开发中,性能和稳定性是衡量系统质量的重要指标。为了确保应用程序在高负载情况下仍能正常运行,压力测试变得尤为重要。Apache JMeter 是一…...
cesium 与 threejs 对比
Cesium 和 Three.js 都是用于在 Web 浏览器中创建和渲染 3D 图形的强大 JavaScript 库,但它们有显著的不同之处,主要体现在应用领域、功能集和使用场景上。 以下是两者之间的对比: 1. 应用场景 Three.js: 适用于广泛的 3D 图形应用ÿ…...
探索QScreen的信号与槽:动态响应屏幕变化
在处理屏幕显示和多显示器环境时,QScreen 提供了一些特有的信号,这些信号可以在屏幕的变化时通知应用程序,帮助我们动态地适配和响应显示设备的变化。今天,我们将深入探讨如何使用 QScreen 的信号与槽,并展示适用的使用…...
vLLM项目加入PyTorch生态系统,引领LLM推理新纪元
近日,vLLM项目宣布正式成为PyTorch生态系统的一部分,标志着该项目与PyTorch的合作进入了一个全新的阶段。本文将从以下几个方面进行介绍,特别提醒:安装方案在第四个部分,可选择性阅读。 vLLM项目概述 vLLM的成就与实际…...
索引-介绍结构语法
一.概述: 1.当给某个字段创建索引后,就会把字段生成二叉排序树进行查找,大大增加了查找效率,比不创建索引时用的全表扫描好得多。 2.二叉排序树:小的在左边,大的在右边(查找和存放都遵循这个原则)。 3.注…...
SpringBoot整合JDBC
讲到这里,基本上我们就可以使用SpringBoot来开发Web项目视图显示和业务逻辑代码,但是要做一个完成案例,我们还差一点点,就是怎么访问数据库,获取数据,接下来我们就看怎么用SpringBoot整合我们前面已经讲过的…...
XXE靶场
XXE-lab 靶场 靶场网址:http://172.16.0.87/ 第一步我们看到网站有登录框我们试着用 bp 去抓一下包 将抓到的包发到重放器中 然后我们构建palody <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "php://filter/readconvert.base64-encode/resourceC:/flag/fla…...
Elasticsearch:使用 Open Crawler 和 semantic text 进行语义搜索
作者:来自 Elastic Jeff Vestal 了解如何使用开放爬虫与 semantic text 字段结合来轻松抓取网站并使其可进行语义搜索。 Elastic Open Crawler 演练 我们在这里要做什么? Elastic Open Crawler 是 Elastic 托管爬虫的后继者。 Semantic text 是 Elasti…...
Facebook的隐私保护政策:用户数据如何在平台上被管理?
在当今数字化世界,社交平台如何管理用户数据并保护隐私成为了一个热点话题。作为全球最大的社交网络,Facebook(现Meta)在数据隐私方面的政策备受关注。本文将简要介绍Facebook的隐私保护措施,以及用户数据如何在平台上…...
【ETCD】【源码阅读】深入解析 EtcdServer.applySnapshot方法
今天我们来一步步分析ETCD中applySnapshot函数 一、函数完整代码 函数的完整代码如下: func (s *EtcdServer) applySnapshot(ep *etcdProgress, apply *apply) {if raft.IsEmptySnap(apply.snapshot) {return}applySnapshotInProgress.Inc()lg : s.Logger()lg.In…...
HBase是什么,HBase介绍
官方网站:Apache HBase – Apache HBase Home HBase是一个分布式的、面向列的NoSQL数据库,主要用于存储和处理海量数据。它起源于Google的BigTable论文,是Apache Hadoop项目的子项目。HBase设计用于高可靠性、高性能和可伸…...
【Rust自学】3.3. 数据类型:复合类型
3.3.0. 写在正文之前 欢迎来到Rust自学的第三章,一共有6个小节,分别是: 变量与可变性数据类型:标量类型数据类型:复合类型(本文)函数和注释控制流:if else控制流:循环 通过第二章…...
【C++】小乐乐求和问题的高效求解与算法对比分析
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯问题描述与数学模型1.1 题目概述1.2 输入输出要求1.3 数学建模 💯方法一:朴素循环求和法2.1 实现原理2.2 分析与问题2.3 改进方案2.4 性能瓶颈与结论…...
cv_unet_image-colorization图像上色入门必看:纯本地运行无网络依赖实操手册
cv_unet_image-colorization图像上色入门必看:纯本地运行无网络依赖实操手册 本文总计约3800字,完整阅读约需12分钟,包含详细的环境配置、操作步骤和实用技巧,适合零基础用户快速上手。 1. 引言:让黑白照片重现光彩 你…...
Chrome for Testing 终极配置指南:5个实战技巧让浏览器自动化测试更高效
Chrome for Testing 终极配置指南:5个实战技巧让浏览器自动化测试更高效 【免费下载链接】chrome-for-testing 项目地址: https://gitcode.com/gh_mirrors/ch/chrome-for-testing Chrome for Testing 是 GoogleChromeLabs 团队专门为浏览器自动化测试设计的…...
FIFA 23 Live Editor终极指南:10分钟掌握实时游戏修改技巧
FIFA 23 Live Editor终极指南:10分钟掌握实时游戏修改技巧 【免费下载链接】FIFA-23-Live-Editor FIFA 23 Live Editor 项目地址: https://gitcode.com/gh_mirrors/fi/FIFA-23-Live-Editor FIFA 23 Live Editor 是一款专为FIFA 23玩家设计的革命性实时编辑工…...
高可用外卖返利 CPS 平台:Java 后端异步回调处理机制深度解析
高可用外卖返利 CPS 平台:Java 后端异步回调处理机制深度解析 在构建外卖返利(CPS)系统时,异步回调(Callback)机制是连接用户授权、订单同步与佣金结算的神经中枢。美团、饿了么等平台的用户授权与订单状态…...
计算机毕业设计:Python中国地铁网络智能分析系统 Flask框架 数据分析 可视化 高德地图 数据挖掘 机器学习 爬虫(建议收藏)✅
博主介绍:✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌ > 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与…...
用STC32G的HSPWM做个数控电源:从BUCK电路到PID调参,我的DIY踩坑全记录
从零打造STC32G数控电源:我的BUCK电路实战与PID调参血泪史 作为一个常年泡在电子实验室的硬件爱好者,开关电源一直是我又爱又恨的领域。去年冬天,当我第N次烧毁某宝买的降压模块后,终于下定决心自己打造一台高精度数控电源。这次…...
【typst-rs】Typst CLI 入口代码解析
这段代码是 Typst CLI 工具的入口点(main.rs),Typst 是一个基于 Rust 的排版系统。让我详细解析这段代码的结构和功能。 模块声明 (1-18行) mod args; mod compile; mod completions; mod deps; mod download; mod eval; mod fonts; mod gree…...
云服务器是如何保障数据安全的
在云服务器中,访问控制机制是重要的安全屏障。云服务商会实施严格的身份认证,用户需要通过密码、密钥、生物识别等多种方式进行身份验证,只有通过验证的用户才能获得相应的操作权限。同时,基于角色的访问控制将用户分配到不同角色…...
彻底卸载Windows 10 OneDrive:开源脚本的完整解决方案
彻底卸载Windows 10 OneDrive:开源脚本的完整解决方案 【免费下载链接】OneDrive-Uninstaller Batch script to completely uninstall OneDrive in Windows 10 项目地址: https://gitcode.com/gh_mirrors/on/OneDrive-Uninstaller 你是否曾为Windows 10内置的…...
2026AI大模型入门学习教程(建议收藏),大模型入门学习路线,非常详细看这一篇就够了!
一、LLM Fundamentals 基础 1. 机器学习的数学基础 在掌握机器学习之前,理解支撑这些算法的基本数学概念非常重要。 线性代数:这是理解许多算法(特别是深度学习算法)的关键。主要概念包括向量、矩阵、行列式、特征值和特征向量、…...
