【数据结构与算法】稀疏数组

文章目录

  • 一:为什么会使用稀疏数组
    • 1.1 先看一个实际的需求
    • 1.2 基本介绍
      • 1.2.1 稀疏数组的处理方法
      • 1.2.2 数组的举例说明
      • 1.2.3 应用实例
      • 1.2.4 整体思路分析
        • 二维数组转稀疏数组的思路
        • 稀疏数组转原始的二维数组的思路
  • 二:代码实现
    • 2.1 创建一个原始的11*11二维数组
    • 2.2 将二维数组转化为稀疏数组
    • 2.3 将稀疏数组恢复成原始的二维数组
    • 2.4 完整代码奉上

一:为什么会使用稀疏数组

1.1 先看一个实际的需求

  • 编写的五子棋程序中,有存盘退出和续上盘的功能
    在这里插入图片描述
  • 问题分析:因为该二维数组的很多值是默认值0, 因此记录了很多没有意义的数据。所以此时我们可以简化一下二维数组,使用稀疏数组来解决此问题。

1.2 基本介绍

当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。

1.2.1 稀疏数组的处理方法

  • 记录数组总共有几行几列,有多少个不同的值
  • 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模。

1.2.2 数组的举例说明

在这里插入图片描述
注:

  1. 数组的下标都是从0开始,所以第一行,第四列用(0,3)表示
  2. 第一行【0】6 7 8 表示,共有6行、7列,有效数据有8个,其他行表示这8个数据具体的坐标。

1.2.3 应用实例

  1. 使用稀疏数组,来保留类似前面的二维数组(棋盘,地图等等)
  2. 把稀疏数组存盘,并且可以从新恢复原来的二维数组数

1.2.4 整体思路分析

在这里插入图片描述

二维数组转稀疏数组的思路

  1. 遍历原始的二维数组,得到有效数据的个数sum
  2. 根据sum就可以创建稀疏数组(sparseArr ) int[sum+1][3]
  3. 将二维数组的有效数据数据存入到 稀疏数组

稀疏数组转原始的二维数组的思路

  1. 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的 chessArr2=int[11][11]
  2. 在读取稀疏数组后几行的数据,并赋给 原始的二维数组 即可

二:代码实现

2.1 创建一个原始的11*11二维数组

0:表示没有棋子 1:表示黑子 2:表示白子

		int[][] chessArr1 = new int[11][11];
        chessArr1[1][2] = 1;
        chessArr1[2][3] = 2;
        chessArr1[4][9] = 3;
        chessArr1[6][3] = 4;
        chessArr1[9][10] = 5;
        //输出二维数组
        System.out.println("原始的二维数组");
        for (int[] row : chessArr1) {
            for (int data : row) {
                //换行输出
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }

在这里插入图片描述

2.2 将二维数组转化为稀疏数组

  1. 遍历原始的二维数组,得到有效数据的个数sum
int sum = 0;
        for (int i = 0; i < chessArr1.length; i++) {
            for (int j = 0; j < chessArr1[0].length; j++) {
                if(chessArr1[i][j] != 0) {
                    sum = sum + 1;
                }
            }
        }
        System.out.println("sum: " + sum);

输出:sum=5

  1. 创建对应的稀疏数组
int[][] sparseArray = new int[sum + 1][3];
  1. 给稀疏数组第一行赋值
		sparseArray[0][0] = chessArr1.length;
        sparseArray[0][1] = chessArr1[0].length;
        sparseArray[0][2] = sum;
  1. 给第其他行赋值,遍历二维数组将非0值存放到稀疏数组里面
//count用于记录第几个非0数据
        int count = 1;
        for (int i = 0; i < chessArr1.length; i++) {
            for (int j = 0; j < chessArr1[0].length; j++) {
                if(chessArr1[i][j] != 0) {
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = chessArr1[i][j];
                    count = count + 1;
                }
            }
        }

  1. 输出稀疏数组
		System.out.println();
        System.out.println("得到的稀疏数组");
        for (int[] row : sparseArray) {
            for (int data : row) {
                //换行输出
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }

在这里插入图片描述

2.3 将稀疏数组恢复成原始的二维数组

  1. 先读取稀疏数组的第一行。根据第一行的数据,创建二维数组
int[][] chessArr2 = new int[sparseArray[0][0]][sparseArray[0][1]];
  1. 读取稀疏数组的后几行数据(从第二行开始),并赋值给原始的二维数组即可
for (int i = 1; i < sparseArray.length; i++) {
            chessArr2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        }
        System.out.println("转化后的的二维数组");
        for (int[] row : chessArr1) {
            for (int data : row) {
                //换行输出
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }

在这里插入图片描述

2.4 完整代码奉上

package com.sysg.dataStructuresAndAlgorithms.array;

import java.util.Arrays;

/**
 * 稀疏数组
 *
 * 一:二维数组转稀疏数组的思路
 * 1.遍历原始的二维数组,得到有效数据的个数sum
 * 2.根据sum就可以创建稀疏数组(sparseArr ) int[sum+1][3]
 *
 *
 * 二:将二维数组的有效数据数据存入到 稀疏数组
 * 1.稀疏数组转原始的二维数组的思路
 * 2.先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的 chessArr12=int[11][11]
 * 3.在读取稀疏数组后几行的数据,并赋给 原始的二维数组 即可
 *
 * @author shi.guangqiang
 */
public class SparseArray {

    public static void main(String[] args) {
        //1.创建一个原始的二维数组 11*11
        //0:表示没有棋子 1:表示黑子 2:表示白子
        int[][] chessArr1 = new int[11][11];
        chessArr1[1][2] = 1;
        chessArr1[2][3] = 2;
        chessArr1[4][9] = 3;
        chessArr1[6][3] = 4;
        chessArr1[9][10] = 5;
        //输出二维数组
        System.out.println("原始的二维数组");
        for (int[] row : chessArr1) {
            for (int data : row) {
                //换行输出
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }

         //2.将二维数组转化为稀疏数组的思路
         //2.1 遍历原始的二维数组,得到有效数据的个数sum
        int sum = 0;
        for (int i = 0; i < chessArr1.length; i++) {
            for (int j = 0; j < chessArr1[0].length; j++) {
                if(chessArr1[i][j] != 0) {
                    sum = sum + 1;
                }
            }
        }
        System.out.println("sum: " + sum);

        //2.2 创建对应的稀疏数组
        int[][] sparseArray = new int[sum + 1][3];

        //2.3 给稀疏数组赋值
        //2.3.1 给第一行赋值
        sparseArray[0][0] = chessArr1.length;
        sparseArray[0][1] = chessArr1[0].length;
        sparseArray[0][2] = sum;
        //2.3.2 给第其他行赋值,遍历二维数组将非0值存放到稀疏数组里面
        //count用于记录第几个非0数据
        int count = 1;
        for (int i = 0; i < chessArr1.length; i++) {
            for (int j = 0; j < chessArr1[0].length; j++) {
                if(chessArr1[i][j] != 0) {
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = chessArr1[i][j];
                    count = count + 1;
                }
            }
        }

        //3.输出稀疏数组
        System.out.println();
        System.out.println("得到的稀疏数组");
        for (int[] row : sparseArray) {
            for (int data : row) {
                //换行输出
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }

        //4.将稀疏数组恢复成原始的二维数组
        //4.1 先读取稀疏数组的第一行。根据第一行的数据,创建二维数组
        int[][] chessArr2 = new int[sparseArray[0][0]][sparseArray[0][1]];
        //4.2 读取稀疏数组的后几行数据(从第二行开始),并赋值给原始的二维数组即可
        for (int i = 1; i < sparseArray.length; i++) {
            chessArr2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        }
        System.out.println("转化后的的二维数组");
        for (int[] row : chessArr1) {
            for (int data : row) {
                //换行输出
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }


    }

}

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

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

相关文章

每天一道leetcode:剑指 Offer 12. 矩阵中的路径(中等DFS深度优先遍历)

今日份题目&#xff1a; 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元…

HCIA---动态路由---RIP协议

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 目录 前言 一.动态路由 二.动态路由协议分类 IGP&#xff1a;内部网关协议 EGP:外部网关协议 三.RIP协议概述 RIP版本分类&#xff1a; RIP三要素&#xff1a; 思维…

全景图!最近20年,自然语言处理领域的发展

夕小瑶科技说 原创 作者 | 小戏、Python 最近这几年&#xff0c;大家一起共同经历了 NLP&#xff08;写一下全称&#xff0c;Natural Language Processing&#xff09; 这一领域井喷式的发展&#xff0c;从 Word2Vec 到大量使用 RNN、LSTM&#xff0c;从 seq2seq 再到 Attenti…

【计算机网络】12、frp 内网穿透

文章目录 一、服务端设置二、客户端设置 frp &#xff1a;A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet。是一个专注于内网穿透的高性能的反向代理应用&#xff0c;支持 TCP、UDP、HTTP、HTTPS 等多种协议&#xff0c;且…

SQL Server Reporting Services 报错:报表服务器无法访问服务帐户的私钥

解决这个问题&#xff0c;有小伙伴提到可以使用命令 exec DeleteEncryptedContent 但这对这边的环境时行不通的&#xff0c;我在【服务账户】的配置和【数据库】的配置中到使用了域账户&#xff0c;试了几次都不行。改成使用内置账户就好了。具体原因还没扒拉&#xff08;欢迎…

4-5-tablewidget

文章目录 添加控件&#xff0c;添加行列数widget.cppwidget.h效果 添加控件&#xff0c;添加行列数 widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this)…

linux和C++中的 线程同步与线程安全 对比

线程同步与线程安全 线程进程与线程的区别并发和并行的区别linux线程常用接口函数函数定义函数使用 多线程理解 线程同步五个线程同时启动&#xff0c;每一个循环打印3次五个线程&#xff0c;每一个循环1000 结果是<5000代码和测试结果测试结果分析可以用信号量和互斥锁解决…

一文走进时序数据库性能测试工具 TSBS

一、背景 在物联网、车联网等时序数据场景中&#xff0c;数据的高速写入能力至关重要&#xff0c;会对产品方案的可用性、可靠性和扩展性产生影响。 以物联网为例&#xff0c;当面临千万甚至上亿设备、平均每个设备采集几十个到几百个指标时&#xff0c;每秒生成的数据将达到…

vue3 setup+Taro3 调用原生小程序自定义年月日时分多列选择器,NutUI改造

vue3 setupTaro3 调用原生小程序自定义年月日时分多列选择器&#xff0c;NutUI改造 NutUI 有日期时间选择器&#xff0c;但是滑动效果太差&#xff0c;卡顿明显。换成 原生小程序 很顺畅 上代码&#xff1a; <template><view><pickermode"multiSelector&…

Grafana+Prometheus技术文档-进阶使用-监控spring-boot项目

阿丹&#xff1a; 之前已经实现了使用Prometheus来对服务器进行了监控和仪表盘的创建&#xff0c;现在就需要对这些监控方法使用在spring-boot中去。 实现思路&#xff1a; 1、集成Actuator 2、加入Prometheus的依赖 3、配置开放端口、以及开放监控 4、配置Prometheus中的配置…

Linux命令200例:tree用于以树状结构显示文件和目录

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

【Terraform学习】保护敏感变量(Terraform配置语言学习)

实验步骤 创建 EC2 IAM 角色 导航到IAM 在左侧菜单中&#xff0c;单击角色 。单击创建角色该按钮以创建新的 IAM 角色。 在创建角色部分&#xff0c;为角色选择可信实体类型&#xff1a; AWS 服务 使用案例:EC2 单击下一步 添加权限&#xff1a;现在&#xff0c;您可以看到…

穿越未来:探索虚拟现实科技的未来前景

虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;科技&#xff0c;正如一颗崭新的明星&#xff0c;迅猛崛起&#xff0c;为人类带来前所未有的体验和想象空间。随着科技的飞速发展&#xff0c;VR 科技的未来充满了无限的可能性&#xff0c;正将我们引向一个…

VUE+ElementUI的表单验证二选一必填项,并且满足条件后清除表单验证提示

上代码 <el-form-item label"出库单号" prop"ecode" ref"ecode" :rules"rules.ecode"><el-input v-model"queryParams.ecode" placeholder"出库单号和出库箱号至少填写一项" clearable style"width…

SpringBoot启动报错:java: 无法访问org.springframework.boot.SpringApplication

报错原因&#xff1a;jdk 1.8版本与SpringBoot 3.1.2版本不匹配 解决方案&#xff1a;将SpringBoot版本降到2系列版本(例如2.5.4)。如下图&#xff1a; 修改版本后切记刷新Meavn依赖 然后重新启动即可成功。如下图&#xff1a;

Linux如何开启指定端口号

本文已收录于专栏 《运维》 目录 概念说明防火墙端口号 提供服务具体分类具体操作防火墙操作端口号操作 总结提升 概念说明 防火墙 防火墙是一种网络安全设备或软件&#xff0c;用于监控和控制网络流量&#xff0c;保护网络免受恶意攻击和未经授权的访问。防火墙可以根据预定义…

MySQL 数据类型总结

整形数据类型 1字节 8bit 2^8256

VBA_MF系列技术资料1-152

MF系列VBA技术资料 为了让广大学员在VBA编程中有切实可行的思路及有效的提高自己的编程技巧&#xff0c;我参考大量的资料&#xff0c;并结合自己的经验总结了这份MF系列VBA技术综合资料&#xff0c;而且开放源码&#xff08;MF04除外&#xff09;&#xff0c;其中MF01-04属于定…

iOS问题记录 - Xcode 15安装低版本iOS模拟器(持续更新)

文章目录 前言开发环境问题描述问题分析1. 定位问题2. 逆向分析2.1. IDA Free2.2. Hopper Disassembler Demo 3. 模拟器日志4. supportedArchs 解决方案最后 前言 最近新需求很多&#xff0c;项目改动很大&#xff0c;开发完成后想测一遍在低版本iOS系统上的兼容性&#xff0c…