数据结构与算法—稀疏数组

news2025/1/11 2:38:59

稀疏数组

稀疏数组与二维数组

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

二维数组转成稀疏数组:
在这里插入图片描述
从图中可以看出:
稀疏数组的行、列、值的
(1)[0]行:二维数组 a(6*7)的行值,列值,以及元素值不为0的个数(8个)
(2)[1]行:二维数组的值 22 是第 a[0] 行,第 a[3] 列
(3)[2]行:二维数组的值 15 是第 a[0] 行,第 a[6] 列
(4)[3]行:二维数组的值 11 是第 a[1] 行,第 a[1] 列

从而知道:
稀疏数组的value 值,就是二维数组中不为0的元素值,一行一行,从上到下记
稀疏数组的行,列,就是对应value值在二维数组中的位置,比如22 在a[0][3],11在a[1][1],-6在a[2][3]。

稀疏数组和二维数组的转换

在这里插入图片描述
根据思路可以书写代码进行测试:

  1. 创建二维数组
public class Demo {

    public static void main(String[] args) {
        // 创建二维数组
        int[][] array = new int[11][11];
        array[1][2] = 1;
        array[2][3] = 2;
        array[3][4] = 2;
        // 遍历数组打印看看
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i].length; j++) {
                System.out.print(a[i][j] + " ");
            }
            System.out.println();
        }
    }
}

可以得到如下的数组:
在这里插入图片描述

  1. 将得到的二维数组转换成稀疏数组
class ArrayUtil {
	// 传入二维数组
    public void convert(int[][] a) {
        // 记录二维数组不为0的个数
        int sum = 0;
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i].length; j++) {
                if (a[i][j] != 0) {
                    sum++;
                }
            }
        }

        // 根据sum创建稀疏数组,稀疏数组固定列为 3 列,包括row, col, val
        int[][] sparseArray = new int[sum + 1][3];
        // 行 row
        sparseArray[0][0] = a.length;
        // 列 col
        sparseArray[0][1] = a[0].length;
        // 值 val
        sparseArray[0][2] = sum;

        // 遍历二维数组,将不为 0 的值放入稀疏数组中
        // count 用于在稀疏数组中记录是第几个非 0 的数值
        int count = 0;
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i].length; j++) {
                // 遍历稀疏数组并赋值
                if (a[i][j] != 0) {
                    count++;
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = a[i][j];
                }
            }
        }

        // 输出稀疏数组
        System.out.println("二维数组对应的稀疏数组:");
        for (int i = 0; i < sparseArray.length; i++) {
            System.out.printf("%d\t%d\t%d\t\n", sparseArray[i][0], sparseArray[i][1], sparseArray[i][2]);
        }
    }

}
  1. 完整代码
public class Demo {

    public static void main(String[] args) {
        // 创建二维数组
        int[][] array = new int[11][11];
        array[1][2] = 1;
        array[2][3] = 2;
        array[3][4] = 2;
        // 遍历数组打印看看
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j] + " ");
            }
            System.out.println();
        }
        new ArrayUtil().convert(array);
    }
}

class ArrayUtil {
	// 传入二维数组
    public void convert(int[][] a) {
        // 查询二维数组不为0的个数
        int sum = 0;
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i].length; j++) {
                if (a[i][j] != 0) {
                    sum++;
                }
            }
        }

        // 根据sum创建稀疏数组,稀疏数组固定列为 3 列,包括row, col, val
        int[][] sparseArray = new int[sum + 1][3];
        // 行 row
        sparseArray[0][0] = a.length;
        // 列 col
        sparseArray[0][1] = a[0].length;
        // 值 val
        sparseArray[0][2] = sum;

        // 遍历二维数组,将不为0的值放入稀疏数组中
        // count 用于在稀疏数组中记录是第几个非 0 的数值
        int count = 0;
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i].length; j++) {
                // 遍历稀疏数组并赋值
                if (a[i][j] != 0) {
                    count++;
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = a[i][j];
                }
            }
        }

        // 输出稀疏数组
        System.out.println("二维数组对应的稀疏数组:");
        for (int i = 0; i < sparseArray.length; i++) {
            System.out.printf("%d\t%d\t%d\t\n", sparseArray[i][0], sparseArray[i][1], sparseArray[i][2]);
        }
    }

}

打印:
在这里插入图片描述

  1. 将稀疏数组转二维数组
    在上面的基础上,在后面添加代码
		// 稀疏数组转成二维数组
        System.out.println("稀疏数组转成二维数组:");

        // 创建二维数组
        int[][] chessArr2 = new int[sparseArray[0][0]][sparseArray[0][1]];
        // 遍历稀疏数组非 0 值的行,并赋值
        for (int i = 1; i < sparseArray.length; i++) {
            // 将稀疏数组中0, 1列的值对应到二维数组下标;2列的值对应到所在下标的值
            chessArr2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        }

        // 遍历数组打印看看
        for (int i = 0; i < chessArr2.length; i++) {
            for (int j = 0; j < chessArr2[i].length; j++) {
                System.out.print(chessArr2[i][j] + " ");
            }
            System.out.println();
        }
  1. 完整代码:
public class Demo {

    public static void main(String[] args) {
        // 创建二维数组
        int[][] array = new int[11][11];
        array[1][2] = 1;
        array[2][3] = 2;
        array[3][4] = 2;
        // 遍历数组打印看看
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j] + " ");
            }
            System.out.println();
        }
        new ArrayUtil().convert(array);
    }
}

class ArrayUtil {

    public void convert(int[][] a) {
        // 查询二维数组不为0的个数
        int sum = 0;
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i].length; j++) {
                if (a[i][j] != 0) {
                    sum++;
                }
            }
        }

        // 根据sum创建稀疏数组,稀疏数组固定列为 3 列,包括row, col, val
        int[][] sparseArray = new int[sum + 1][3];
        // 行 row
        sparseArray[0][0] = a.length;
        // 列 col
        sparseArray[0][1] = a[0].length;
        // 值 val
        sparseArray[0][2] = sum;

        // 遍历二维数组,将不为0的值放入稀疏数组中
        // count 用于在稀疏数组中记录是第几个非 0 的数值
        int count = 0;
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i].length; j++) {
                // 遍历稀疏数组并赋值
                if (a[i][j] != 0) {
                    count++;
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = a[i][j];
                }
            }
        }

        // 输出稀疏数组
        System.out.println("二维数组对应的稀疏数组:");
        for (int i = 0; i < sparseArray.length; i++) {
            System.out.printf("%d\t%d\t%d\t\n", sparseArray[i][0], sparseArray[i][1], sparseArray[i][2]);
        }

        // 稀疏数组转成二维数组
        System.out.println("稀疏数组转成二维数组:");

        // 创建二维数组
        int[][] chessArr2 = new int[sparseArray[0][0]][sparseArray[0][1]];
        // 遍历稀疏数组非 0 值的行,并赋值
        for (int i = 1; i < sparseArray.length; i++) {
            // 将稀疏数组中0, 1列的值对应到二维数组下标;2列的值对应到所在下标的值
            chessArr2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        }

        // 遍历数组打印看看
        for (int i = 0; i < chessArr2.length; i++) {
            for (int j = 0; j < chessArr2[i].length; j++) {
                System.out.print(chessArr2[i][j] + " ");
            }
            System.out.println();
        }

    }


}

将稀疏数组写入磁盘(类五子棋游戏的保存)

到这,完成了稀疏数组和二维数组的转化。接下来,可以将稀疏数组 sparseArray 写入磁盘

		// 将稀疏数组写到磁盘中 map.data
        // 创建缓冲字符输出流
        BufferedWriter bw;
        try {
            bw = new BufferedWriter(new FileWriter("D:\\work\\workspace\\java-learn\\sparseArray\\map.data"));
            // 遍历稀疏数组,写入数据
            for (int i = 0; i < sparseArray.length; i++) {
                bw.write(sparseArray[i][0]+"\t"+sparseArray[i][1]+"\t"+sparseArray[i][2]+"\n");
            }
            // 写完后,将内存缓冲区的数据,刷新到文件中
            bw.flush();
            // 释放资源
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

上述代码执行后,会在相应目录下产生一个map.data文件,直接用txt打开,可以看到有4行3列的数据
在这里插入图片描述

从磁盘将数据取出

		// 从map.data中读取数据
        // 创建缓冲字符输入流
        System.out.println("------------------------------------");
        System.out.println("从文件中读出的稀疏数组:");
        BufferedReader br;
        List<String> list = new ArrayList<>();
        try {
            br = new BufferedReader(new FileReader("D:\\work\\workspace\\java-learn\\sparseArray\\map.data"));
            String line;
            while ((line = br.readLine()) != null) {
                // 可以将数据放入list或其他集合中,进行遍历还原出稀疏数组
                list.add(line);
            }
            // 释放资源
            br.close();

            // 创建稀疏数组
            int[][] sarr = new int[list.size()][3];
            // 遍历list数据
            for (int i = 0; i < list.size(); i++) {
                // 根据写入文件时的 \t 制表符分开放入数组中
                String[] s = list.get(i).trim().split("\t");
                sarr[i][0] = Integer.valueOf(s[0]);
                sarr[i][1] = Integer.valueOf(s[1]);
                sarr[i][2] = Integer.valueOf(s[2]);
            }
            // 遍历稀疏数组
            for (int i = 0; i < sarr.length; i++) {
                System.out.printf("%d\t%d\t%d\t\n", sarr[i][0], sarr[i][1], sarr[i][2]);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

可以看到打印出来的数据:
在这里插入图片描述

完整代码

package com.liwang.sparseArray;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author LiWang Chen
 * @Date 2023-01-06 13:26
 * @Version 1.0
 */
public class Demo {

    public static void main(String[] args) {
        // 创建二维数组
        int[][] array = new int[11][11];
        array[1][2] = 1;
        array[2][3] = 2;
        array[3][4] = 2;
        // 遍历数组打印看看
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j] + " ");
            }
            System.out.println();
        }
        new ArrayUtil().convert(array);
    }
}

class ArrayUtil {

    public void convert(int[][] a) {
        // 查询二维数组不为0的个数
        int sum = 0;
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i].length; j++) {
                if (a[i][j] != 0) {
                    sum++;
                }
            }
        }

        // 根据sum创建稀疏数组,稀疏数组固定列为 3 列,包括row, col, val
        int[][] sparseArray = new int[sum + 1][3];
        // 行 row
        sparseArray[0][0] = a.length;
        // 列 col
        sparseArray[0][1] = a[0].length;
        // 值 val
        sparseArray[0][2] = sum;

        // 遍历二维数组,将不为0的值放入稀疏数组中
        // count 用于在稀疏数组中记录是第几个非 0 的数值
        int count = 0;
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i].length; j++) {
                // 遍历稀疏数组并赋值
                if (a[i][j] != 0) {
                    count++;
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = a[i][j];
                }
            }
        }

        // 输出稀疏数组
        System.out.println("二维数组对应的稀疏数组:");
        for (int i = 0; i < sparseArray.length; i++) {
            System.out.printf("%d\t%d\t%d\t\n", sparseArray[i][0], sparseArray[i][1], sparseArray[i][2]);
        }

        // 将稀疏数组写到磁盘中 map.data
        // 创建缓冲字符输出流
        BufferedWriter bw;
        try {
            bw = new BufferedWriter(new FileWriter("D:\\work\\workspace\\java-learn\\sparseArray\\map.data"));
            // 遍历稀疏数组,写入数据
            for (int i = 0; i < sparseArray.length; i++) {
                bw.write(sparseArray[i][0]+"\t"+sparseArray[i][1]+"\t"+sparseArray[i][2]+"\n");
            }
            // 写完后,将内存缓冲区的数据,刷新到文件中
            bw.flush();
            // 释放资源
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }


        // 从map.data中读取数据
        // 创建缓冲字符输入流
        System.out.println("------------------------------------");
        System.out.println("从文件中读出的稀疏数组:");
        BufferedReader br;
        List<String> list = new ArrayList<>();
        try {
            br = new BufferedReader(new FileReader("D:\\work\\workspace\\java-learn\\sparseArray\\map.data"));
            String line;
            while ((line = br.readLine()) != null) {
                // 可以将数据放入list或其他集合中,进行遍历还原出稀疏数组
                list.add(line);
            }
            // 释放资源
            br.close();

            // 创建稀疏数组
            int[][] sarr = new int[list.size()][3];
            // 遍历list数据
            for (int i = 0; i < list.size(); i++) {
                // 根据写入文件时的 \t 制表符分开放入数组中
                String[] s = list.get(i).trim().split("\t");
                sarr[i][0] = Integer.valueOf(s[0]);
                sarr[i][1] = Integer.valueOf(s[1]);
                sarr[i][2] = Integer.valueOf(s[2]);
            }
            // 遍历稀疏数组
            for (int i = 0; i < sarr.length; i++) {
                System.out.printf("%d\t%d\t%d\t\n", sarr[i][0], sarr[i][1], sarr[i][2]);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


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

        // 创建二维数组
        int[][] chessArr2 = new int[sparseArray[0][0]][sparseArray[0][1]];
        // 遍历稀疏数组非 0 值的行,并赋值
        for (int i = 1; i < sparseArray.length; i++) {
            // 将稀疏数组中0, 1列的值对应到二维数组下标;2列的值对应到所在下标的值
            chessArr2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        }

        // 遍历数组打印看看
        for (int i = 0; i < chessArr2.length; i++) {
            for (int j = 0; j < chessArr2[i].length; j++) {
                System.out.print(chessArr2[i][j] + " ");
            }
            System.out.println();
        }

    }


}

在这里插入图片描述
在这里插入图片描述
可以看看我的个人博客:
网站:https://www.fuzm.wang / https://liwangc.gitee.io
—————————————————————————
作为初学者,很多知识都没有掌握,见谅,如有错误请指出,以期进步,感谢!。后续有新的学习,继续补充上来。

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

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

相关文章

linux下软硬链接到底是什么?

文章目录前言硬链接软链接前言 在了解软硬链接之前&#xff0c;可以先来了解一下磁盘以及inode到底是什么 Linux文件管理—磁盘上文件如何管理&#xff08;inode&#xff09; 硬链接 什么是硬链接 在Linux下&#xff0c;系统标识文件的唯一方式就是inode号&#xff0c;而对…

【初阶数据结构】——双“指针”求解数组常见问题

文章目录前言题目1&#xff1a;移除元素思路1&#xff1a;暴力求解思路2&#xff1a;时间换空间思路3&#xff1a;双指针原地删除&#xff08;解法2的再优化&#xff09;思路分析代码实现题目2&#xff1a;删除有序数组中的重复项思路&#xff1a;双指针代码实现题目3&#xff…

【JavaScript】BOM 学习总结

基础知识&#xff1a; 获取浏览器窗口的尺寸&#xff1a; innerHeight&#xff1a;获取高度 innerWidth&#xff1a;获取宽度 跳转与刷新 location.href location.reload() body><button id"btn">跳转到下一个页面</button><button id"btn…

Java实现文件操作

目录 一、文件概述 二、常见文件操作 1、获取文件路径 2、判断文件存在以及判断类型 3、文件的创建与删除 4、展示文件夹的文件 5、创建文件夹 三、用数据流来读取文件内容 1、操作字节流文件 a、读取字节流文件 b、写字节流文件 2、操作字符流对象 a、读取…

C++ · 入门 · 03 | 函数重载

啊我摔倒了..有没有人扶我起来学习.... 目录前言函数重载1.1 函数重载概念1.2 函数重载的意义1.3 C支持函数重载的原理--名字修饰(name Mangling)1.4 返回值不同能否构成函数重载?前言 自然语言中&#xff0c;一个词可以有多重含义&#xff0c;人们可以通过上下文来判断该词真…

小米 2021 秋招面试总结

岗位:嵌入式软件工程师(相机驱动岗) 面试时间: 40 分钟 薪资: 28w+ 面试过程 面试官上来先来了一段他自己的自我介绍,流程还是比较规范的。 1、请进行一个简单的自我介绍(2分钟) 2、C语言全局变量可否定义在头文件中? 回答:不能,并且这不是一个好的习惯。 3…

【自学C++】C++输出cout

C输出cout C输出cout教程 在 C 语言 中我们需要输出一个 变量&#xff0c;可以使用 printf。printf 函数 在输出时&#xff0c;我们必须要指定输出的数据类型对应的格式化符&#xff0c;挺不方便。 在 C 中&#xff0c;我们要输出变量&#xff0c;直接使用 std 命名空间中的…

国科大抢课避坑+选课指南+教务系统操作

博客园&#xff1a; https://www.cnblogs.com/phoenixash/p/13669461.html 9月12日12&#xff1a;30&#xff0c;本菜鸡终于经历了国科大传说中的抢课大战&#xff0c;虽然自己之前准备的较多&#xff0c;但还是在抢课的时候掉进了不少坑里&#xff0c;趁现在还记忆犹新&#x…

【pandas】教程:10-文本数据的操作

Pandas 文本数据的操作 本节使用的数据为 data/titanic.csv&#xff0c;链接为 pandas案例和教程所使用的数据-机器学习文档类资源-CSDN文库 读入数据 import pandas as pd titanic pd.read_csv("data/titanic.csv")PassengerId Survived Pclass \ 0 …

指针进阶(2)

Tips 1. 2. 3. 碰到地址就等价于指针变量&#xff0c;里面存放着该地址的指针变量 4. 数组指针是存放数组的地址&#xff0c;指向的是一个数组&#xff1b;函数指针存放的是函数的地址&#xff0c;指向的是一个函数。 5. 地址就是指针&#xff0c;地址就是指针 6. 数…

LeetCode 138. 复制带随机指针的链表(C++)

思路&#xff1a; 用哈希表实现&#xff0c;创建一个哈希表来对应原链表中的每一个节点&#xff0c;这样也可以将原链表中的所有结点的next和random关系映射到哈希表复制链表中。 原题链接&#xff1a;https://leetcode.cn/problems/copy-list-with-random-pointer/description…

1658. 将 x 减到 0 的最小操作数

解法一&#xff1a;双指针 首先&#xff0c;每次操作可以移除数组 nums 最左边或最右边的元素&#xff0c;那么相当于求出l和rl和rl和r使得[0,l][r,n−1][0, l][r,n-1][0,l][r,n−1]之间所有元素之和等于xxx,并且元素个数最少。我们可以通过双重循环枚举l和r变量l和r变量l和r变…

马哥架构第1周课程作业

马哥架构第1周课程作业一. 画图解释一次web请求的过程。涉及tcp/ip, dns, nginx&#xff0c;wsgi。二. 编译安装nginx, 详细解读常用参数。三. 基于nginx完成动静分离部署 lamp。php到后端php-fpm, static/ 在nginx本地。3.1 配置 nginx 实现反向代理的动静分离3.2 准备后端 ht…

equals和==的区别

目录 1.基本数据类型和引用数据类型的说明 2. 3.equals 1.基本数据类型和引用数据类型的说明 基本数据类型&#xff1a;byte&#xff0c;short&#xff0c;int&#xff0c;long&#xff0c;float&#xff0c;double&#xff0c;char&#xff0c;boolean。 对应的默认值&…

2-4进程管理-死锁

文章目录一.死锁的概念二.死锁的处理策略1.死锁预防&#xff1a;破坏必要条件&#xff0c;让死锁无法发生2.避免死锁&#xff1a;在动态分配资源的过程中&#xff0c;用一些算法防止系统进入不安全状态&#xff08;1&#xff09;银行家算法&#xff08;2&#xff09;系统安全状…

Java if else分支结构精讲

Java 支持两种选择语句&#xff1a;if 语句和 switch 语句。其中 if 语句使用布尔表达式或布尔值作为分支条件来进行分支控制&#xff0c;而 switch 语句则用于对多个整型值进行匹配&#xff0c;从而实现分支控制。这些语句允许你只有在程序运行时才能知道其状态的情况下&#…

2022:不恋过往,不畏将来

一、开篇 少年有山海&#xff0c;踏过皆繁华。岁月不居&#xff0c;时节如流&#xff0c;时间在指尖悄悄流逝&#xff0c;人生即将翻开新的一年的篇章。2022年&#xff0c;注定是一个不平凡的年份&#xff0c;这一年&#xff0c;我们从关心世界到关心国家&#xff0c;最后关心自…

2023年12306购票平台自动化购票二|解决车次查找与预定

目录 一、说明 1.1、背景 1.2、说明 二、步骤 2.1、点击去购票 2.2、在搜索框中输入车次信息 2.3、点击查找 2.4、出现车次信息&#xff0c;进行筛选&#xff0c;如果有票则点击计入预定车票界面 三、结果 四、小节 一、说明 1.1、背景 接上文&#xff0c;春运抢不到…

适用于 Windows 的 5 大 PDF 编辑器

“如何在 Windows 7/8/10/11 上编辑 PDF 文件&#xff1f;” “适用于 Windows 7/8/10/11的最佳 PDF 编辑器是什么&#xff1f;” 升级到 Windows 7/8/10/11 后&#xff0c;你会发现很多应用程序在新的 Windows 系统上无法运行&#xff0c;包括 PDF 编辑器。然而&#xff0c;一…

POJ 3070 Fibonacci

Time Limit: 1000MSMemory Limit: 65536KTotal Submissions: 30932Accepted: 20284 Description In the Fibonacci integer sequence, F0 0, F1 1, and Fn Fn − 1 Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are: 0, 1, 1, 2, 3,…