使用Java对稀疏数组的压缩与还原

news2024/12/23 9:46:50

稀疏矩阵的压缩与还原

稀疏数组中元素个数很少或者有大量的重复值,如果直接保存保存,会浪费很多空间,这时,就可以考虑对数组进行压缩存储。
先定义一个稀疏数组

//创建一个二维数组 11 * 11
int[][] array1 = new int[11][11];
//给一些元素赋值
array1[1][2] = 1;
array1[2][3] = 2;
array1[4][4] = 1;
array1[8][5] = 2;

打印初始数组

//输出原始数组
System.out.println("输出原始数组");
for (int[] arr : array1) {
    System.out.println(Arrays.toString(arr));
}

压缩稀疏数组

在压缩数组时,我们可以用稀疏数组的第一行来存储元素数组的大小及原始数组的有效个数。下表为稀疏数组存储的内容,第一行为原始数组的行、列、元素个数。其余行为有效值信息,包括行坐标、列坐标以及有效值。

012
0原始数组行数原始数组列数有效值个数
1行坐标列坐标有效值
2行坐标列坐标有效值
行坐标列坐标有效值

通过原始数组获取有效值个数

//获取有效值个数
int sum = 0;
for (int i = 0; i < array1.length; i++) {
    for (int j = 0; j < array1[i].length; j++) {
        if (array1[i][j] != 0)
            sum++;
    }
}
System.out.println("有效个数为:" + sum);


根据有效值的个数创建稀疏数组,稀疏数组的行数为有效值个数加1,列数固定为3.

int[][] array2 = new int[sum + 1][3];
array2[0][0] = 11;//原始数组行数
array2[0][1] = 11;//原始数组列数
array2[0][2] = sum;//有效值个数

接下来就可以保存原始数组的有效值信息了。先利用一个计数器记录有效值个数。

//遍历二维数组,将非零的值,存放稀疏数组中
int count = 0;//计数作用
for (int i = 0; i < array1.length; i++) {
    for (int j = 0; j < array1[i].length; j++) {
        if (array1[i][j] != 0) {
            count++;//稀疏数组从第二行开始存有效值信息
            array2[count][0] = i;//有效值的行坐标
            array2[count][1] = j;//有效值的列坐标
            array2[count][2] = array1[i][j];//有效值
        }
    }
}

输出稀疏矩阵

for (int i = 0; i < array2.length; i++) {
    System.out.println(array2[i][0] + "\t" + array2[i][1] + "\t" + array2[i][2]);
}

通过稀疏数组还原原始数组

由于稀疏数组的第一行是保存的元素数组的大小,因此我们可以用其来创建一个元素数组的大小。

int[][] array3 = new int[array2[0][0]][array2[0][1]];//array2[0][0]存储的为原始数组的行数,array2[0][1]存储的为原始数组的列数

从稀疏数组下标为1开始遍历,因为1开始才是有效值的信息。如array2[1][0]就是第一个有效值的行坐标,array2[1][1]就是第一个有效值的列坐标,array2[1][2]就是第一个有效值。

for (int i = 1; i < array2.length; i++) {
    array3[array2[i][0]][array2[i][1]] = array2[i][2];
}

最后输出还原后的数组。

//输出还原数组
System.out.println("输出还原数组");
for (int[] arr : array3) {
    System.out.println(Arrays.toString(arr));
}

完整代码

package com.jiang.array;

import java.util.Arrays;

/**
 * @author HaiJaine
 **/
public class ArrayDemo08 {
    public static void main(String[] args) {
        //创建一个二维数组 11 * 11
        int[][] array1 = new int[11][11];
        //给一些元素赋值
        array1[1][2] = 1;
        array1[2][3] = 2;
        array1[4][4] = 1;
        array1[8][5] = 2;
        //输出原始数组
        System.out.println("输出原始数组");
        for (int[] arr : array1) {
            System.out.println(Arrays.toString(arr));
        }
        System.out.println("=================================");
        //转换为稀疏数组保存
        //获取有效值个数
        int sum = 0;
        for (int i = 0; i < array1.length; i++) {
            for (int j = 0; j < array1[i].length; j++) {
                if (array1[i][j] != 0)
                    sum++;
            }
        }
        System.out.println("有效个数为:" + sum);

        //创建一个稀疏数组,第一个行为原始数组的行、列、有效值个数,其余行分别保存元素所在的行、列、元素值
        int[][] array2 = new int[sum + 1][3];
        array2[0][0] = 11;//原始数组行数
        array2[0][1] = 11;//原始数组列数
        array2[0][2] = sum;//有效值个数

        //遍历二维数组,将非零的值,存放稀疏数组中
        int count = 0;//计数作用
        for (int i = 0; i < array1.length; i++) {
            for (int j = 0; j < array1[i].length; j++) {
                if (array1[i][j] != 0) {
                    count++;//稀疏数组从第二行开始存有效值信息
                    array2[count][0] = i;//有效值的行坐标
                    array2[count][1] = j;//有效值的列坐标
                    array2[count][2] = array1[i][j];//有效值
                }
            }
        }
        System.out.println("稀疏数组");
        for (int i = 0; i < array2.length; i++) {
            System.out.println(array2[i][0] + "\t" + array2[i][1] + "\t" + array2[i][2]);
        }
        System.out.println("=================================");
        System.out.println("稀疏矩阵还原");
        //1、读取稀疏数组
        int[][] array3 = new int[array2[0][0]][array2[0][1]];//array2[0][0]存储的为原始数组的行数,array2[0][1]存储的为原始数组的列数
        //2、给其中的元素还原它的值
        for (int i = 1; i < array2.length; i++) {
            array3[array2[i][0]][array2[i][1]] = array2[i][2];
        }
        //输出还原数组
        System.out.println("输出还原数组");
        for (int[] arr : array3) {
            System.out.println(Arrays.toString(arr));
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Window 编辑、删除、新增右键菜单

关于 Window 右键菜单 右键菜单可以在注册表编辑器中新增和修改 建议先下载 registry-finder&#xff0c;查找速度更快&#xff01; 使用管理员模式打开 registry-finder 后&#xff0c;点击 HKEY_CLASSES_ROOT &#xff0c;修改注册表右键菜单的子路径如下表所示 类型路径…

49.在ROS中实现local planner(2)- 实现Purepersuit(纯跟踪)算法

48.在ROS中实现local planner&#xff08;1&#xff09;- 实现一个可以用的模板实现了一个模板&#xff0c;接下来我们将实现一个简单的纯跟踪控制&#xff0c;也就是沿着固定的路径运动&#xff0c;全局规划已经规划出路径点&#xff0c;基于该路径输出相应的控制速度 1. Pur…

Linux系列学习(三) - 进程和库文件

目录 引言&#xff1a; 学习&#xff1a; 基本命令补充&#xff1a; wc命令&#xff1a; more命令&#xff1a; less命令&#xff1a; cat ps命令&#xff1a; kill命令&#xff1a; bg命令&#xff1a; fg命令&#xff1a; 查看系统运行级别&#xff1a; 库文件&a…

unity UGUI系统梳理 - 常用可视化控件

作为一名合格的UI仔>.<&#xff0c;我发现很多UI很久没有使用了&#xff0c;所以我决定做一个UGUI系列博客重新梳理一下 1、Image 在没有放入图片下&#xff0c;image控件长这样 注意 我一般没交互需求的情况下都会把RaycastTarget给点掉&#xff0c;这个不单单是从提…

CAPL脚本DBLookup函数动态访问CAN 报文的属性

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

学习周报3.5

文章目录前言文献阅读摘要介绍方法总结相关性总结前言 本周阅读文献《Multi-step ahead probabilistic forecasting of multiple hydrological》&#xff0c;文献主要提出一种基于三维卷积神经网络、卷积最小门记忆神经网络和变分贝叶斯神经网络的混合深度学习模型&#xff08…

【博学谷学习记录】超强总结,用心分享|狂野大数据课程【Spark SQL函数定义】的总结分析

5.1 如何使用窗口函数 回顾: 窗口函数格式:分析函数 over(partition by xxx order by xxx [asc|desc] [rows between xxx and xxx])学习的相关分析函数有那些? 第一类: row_number() rank() dense_rank() ntile()第二类: 和聚合函数组合使用 sum() avg() max() min() count…

西电软件体系结构核心考点汇总(期末真题+核心考点)

文章目录前言一、历年真题二、核心考点汇总2.1 什么是软件体系架构?(软件体系结构的定义)2.2 架构风格优缺点2.3 质量属性2.4 质量评估前言 主要针对西安电子科技大学《软件体系结构》的核心考点进行汇总。 【期末期间总结资料如下】 针对西电计科院软件工程专业大三《软件体…

【QT】使用QML构建一个简易的计算器界面(三)

前面两篇对计算器界面的布局和显示以及实现功能做了相关优化&#xff0c;但是对输入显示那一块还没有具体的处理步骤&#xff0c;包括对输入表达式的合法性检查&#xff0c;显示框的多行历史显示等功能还需要添加&#xff0c;接下来将从这几个方面对这些功能进行添加。 1、对输…

概率论 1.3 古典概型与几何概型

1.3.1 排列与组合排列从n个不同元素任取r(r<n)个元素排成一列(考虑元素出现的先后次序)&#xff0c;称此为一个排列&#xff0c;此种排列的总数为n(n-1)....(n-r1)n!/(n-r)&#xff01;&#xff0c;若rn,则称为全排列&#xff0c;2.重复排列从n个不同元素中每次取出一个,放回…

GPIO输入和输出以及八种工作模式

一.GPIO的简介 GPIO &#xff08;general purpose input output&#xff09;是通用输入输出端口的简称&#xff0c;简单来说就是软件可控制的引脚&#xff0c;STM32芯片的GPIO引脚与外部传感器连接起来&#xff0c;从而实现与外部通讯、控制以及数据采集的功能。 1.引脚全是GP…

[2.1.1]进程管理——进程的概念、组成、特征

文章目录第二章 进程管理进程的概念、组成、特征&#xff08;一&#xff09;进程的概念&#xff08;二&#xff09;进程的组成——PCB&#xff08;三&#xff09;进程的组成——程序段、数据段补充&#xff1a;程序是如何运行的&#xff1f;&#xff08;四&#xff09;进程的特…

vue3 插槽使用详解

目录1 前言2 插槽的使用2.1 基本使用2.2 具名插槽2.3 动态插槽名2.4 插槽传值3 总结1 前言 Vue 实现了一套内容分发的 API&#xff0c;将 <slot> 元素作为承载分发内容的出口&#xff0c;使用插槽使得vue组件的设计更加灵活。 在vue版本更迭中&#xff0c;尽管插槽的使…

常用的设计模式之一(创建型模式)

设计模式可分为三大类&#xff1a; 创建型模式 (Creational Patterns)结构性模式 (Structural Patterns)行为型模式 (Behavioral Patterns) 模式描述包括创建型模式工厂模式&#xff08;Factory Pattern&#xff09; 抽象工厂模式&#xff08;Abstract Factory Pattern&#…

并发编程——可见性与有序性

如果有兴趣了解更多相关内容&#xff0c;欢迎来我的个人网站看看&#xff1a;耶瞳空间 JMM即Java Memory Model&#xff0c;它定义了主存、工作内存抽象概念&#xff0c;底层对应着CPU寄存器、缓存、硬件内存、CPU指令优化等。JMM体现在以下几个方面&#xff1a; 原子性&…

Web API

DOM API 1、选中页面元素 let elem document.querySelector(CSS选择器); console.log(elem); console.dir(elem); 2、事件 鼠标点击事件 onclick 鼠标移动事件 onmousemove 等等 事件源 .box&#xff0c;事件类型 onlick&#xff0c;事件处理方式 alert(hello) let d…

[Mybatis1]介绍与快速入门

文章目录 Mybatis概述 持久层 框架 Mybatis与JDBC对比 JDBC代码的缺陷 Mybatis简化JDBC Mybatis快速入门案例 整体案例项目结构 1.创建user表&#xff0c;添加数据 2.创建Maven项目&#xff0c;导入坐标 3.编写Mybatis核心配置文件 4.编写数据库返回对象的实体类 5. 编写S…

QML Button详解

1.Button简介 Button表示用户可以按下或单击的按钮控件。按钮通常用于执行一个动作&#xff0c;或回答一个问题。典型的按钮有确定、应用、取消、关闭、是、否和帮助。 Button继承自AbstractButton&#xff0c;提供了以下几种信号。 void canceled() //当按…

Python笔记 -- 列表

文章目录1、列表简介2、修改、添加、删除元素2.1、添加2.2、删除3、排序、倒序4、遍历列表5、创建数值列表6、列表切片7、列表复制8、元组1、列表简介 在Python中用方括号[]表示列表&#xff0c;用逗号隔开表示其元素 通过索引访问列表 names [aa,bb,cc,dd]print(names[0]) …

游戏项目中的程序化生成(PCG):算法之外的问题与问题

本篇讨论的是什么 从概念上讲&#xff0c;PCG&#xff08;程序化生成&#xff09;的含义很广&#xff1a;任何通过规则计算得到的内容&#xff0c;都可算作是PCG。但在很多游戏项目的资料&#xff0c;包括本篇&#xff0c;讨论PCG时特指是&#xff1a;用一些算法/工具(特别是H…