首页 > 编程语言 >数据结构与算法(一): 稀疏数组

数据结构与算法(一): 稀疏数组

时间:2023-07-03 22:56:10浏览次数:51  
标签:sparseArray int originalArray System 算法 数组 数据结构 out

问题引入

在五子棋游戏或类似的游戏中,我们可以把整个棋盘想象成是一个有规律的二维数组,其值由0、1、2三个数字组成,0代表空白区域,1代表白子,2代表黑子。这种情况:即当一个数组中大部分元素为0或者为同一值时,存储该数组数据可以使用稀疏数组来对原始数组进行精简,以减少原始数组中无用数据所占的空间。

普通二维数组与稀疏数组

下图表示的是一个12×12大小的二维数组与之对应的稀疏数组表示,其中普通二维数组中有11个有效值,其余的全为无用数据0填充。稀疏数组的第一行表示有一个12行12列且11个有效数值的二维数组。第二行表示,二维数组中的第2行(从0开始)、第4列的数值为1。从第二行开始,每一行表示的都是二维数组中数值的行列位置和真实值。

在这里插入图片描述 在这里插入图片描述

代码实现

生成二维数组

private int[][] generatorArray() {
	// 初始化二维数组
    int[][] arr = new int[12][12];
    // 二维数组赋值
    arr[2][4] = 1;
    arr[2][5] = 1;
    arr[3][4] = 1;
    arr[3][5] = 1;
    arr[3][6] = 2;
    arr[3][7] = 2;
    arr[4][5] = 2;
    arr[4][6] = 1;
    arr[5][5] = 1;
    arr[5][6] = 2;
    arr[5][7] = 2;
    System.out.println("原始二维数组为:");
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr[i].length; j++) {
            System.out.print(arr[i][j] + "\t");
        }
        System.out.println();
    }
    System.out.println();
    return arr;
}

运行结果

原始二维数组为:
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	1	1	0	0	0	0	0	0	
0	0	0	0	1	1	2	2	0	0	0	0	
0	0	0	0	0	2	1	0	0	0	0	0	
0	0	0	0	0	1	2	2	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	

二维数组转换成稀疏数组

private int[][] toSparseArray(int[][] originalArray) {
	// 获得原始数组行列、有效值初始化稀疏数组
	int sum = 0;
	for (int i = 0; i < originalArray.length; i++) {
	    for (int j = 0; j < originalArray[i].length; j++) {
	        if (originalArray[i][j] != 0) {
	            sum += 1;
	        }
	    }
	}
	// 稀疏数组length为有效值个数+1
	int[][] sparseArray = new int[sum+1][3];
	// 行
	sparseArray[0][0] = originalArray.length;
	// 列
	sparseArray[0][1] = originalArray[0].length;
	// 有效值个数
	sparseArray[0][2] = sum;
	// 赋值
	int count = 0;
	for (int i = 0; i < originalArray.length; i++) {
	    for (int j = 0; j < originalArray[i].length; j++) {
	        if (originalArray[i][j] != 0) {
	            count++;
	            sparseArray[count][0] = i;
	            sparseArray[count][1] = j;
	            sparseArray[count][2] = originalArray[i][j];
	        }
	    }
	}
	// 输出稀疏数组
	System.out.println("转换后的稀疏数组为:");
	for (int i = 0; i < sparseArray.length; i++) {
	    for (int j = 0; j < sparseArray[i].length; j++) {
	        System.out.print(sparseArray[i][j] + "\t");
	    }
	    System.out.println();
	}
	System.out.println();
	return sparseArray;
}

运行结果:

转换后的稀疏数组为:
12	12	11	
2	4	1	
2	5	1	
3	4	1	
3	5	1	
3	6	2	
3	7	2	
4	5	2	
4	6	1	
5	5	1	
5	6	2	
5	7	2

稀疏数组转换为二维数组

private int[][] toOriginalArray(int[][] sparseArray) {
    // 初始化原始数组
    int[][] originalArray = new int[sparseArray[0][0]][sparseArray[0][1]];
    // 从第二个值开始,因为第一个值存的是原始数组的行列、有效值个数等信息
    for (int i = 1; i < sparseArray.length; i++) {
        // 由稀疏数组给原始数组赋值
        originalArray[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
    }
    System.out.println("转换后的二维数组为:");
    for (int i = 0; i < originalArray.length; i++) {
        for (int j = 0; j < originalArray[i].length; j++) {
            System.out.print(originalArray[i][j] + "\t");
        }
        System.out.println();
    }
    return originalArray;
}

实践运用

在真实开发中,一般是将稀疏数组数据在数据库或者文件中进行保存,这里我使用 fastjson2 将稀疏数组转换成 JSON 字符串之后保存到电脑本地(二维数组转稀疏数组),再从本地读取文件内容进行解析(稀疏数组转二维数组)。保存到数据库也是同理的操作。

保存到文件

/**
 * 将JSON字符串保存为文件
 * @param jsonString 转换后的稀疏数组JSON字符串
 * @param fileName 电脑本地文件
 */
private void toFile(String jsonString, String fileName) {
    File file = new File(fileName);
    FileWriter fileWriter = null;
    if (!file.exists()) {
        try {
            file.createNewFile();
            fileWriter = new FileWriter(file);
            char[] chars = jsonString.toCharArray();
            fileWriter.write(chars);
            fileWriter.flush();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        } finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

从文件读取并解析

/**
 * 从文件读取内容
 * @param fileName
 * @return
 * @throws IOException
 */
private String readFile(String fileName) throws IOException {
    File file = new File(fileName);
    FileReader reader = new FileReader(file);
    BufferedReader bufferedReader = new BufferedReader(reader);
    String line = null;
    System.out.println("文件读取内容为:");
    while ((line = bufferedReader.readLine()) != null) {
        System.out.println(line);
        System.out.println();
        return line;
    }
    reader.close();
    bufferedReader.close();
    return line;
}

/**
 * 由JSON字符串转换成原始二维数组
 * @param jsonString
 * @return
 */
private int[][] stringToOriginArray(String jsonString) {
    JSONArray objects = JSON.parseArray(jsonString);
    JSONArray s = (JSONArray) objects.get(0);
    // 初始化原始数组
    int[][] originalArray = new int[(int)s.get(0)][(int)s.get(1)];
    // 从第二个值开始,因为第一个值存的是原始数组的行列、有效值个数等信息
    for (int i = 1; i < objects.size(); i++) {
        JSONArray se = (JSONArray) objects.get(i);
        originalArray[(int)se.get(0)][(int)se.get(1)] = (int)se.get(2);
    }
    System.out.println("JSON字符串转换为二维数组:");
    for (int i = 0; i < originalArray.length; i++) {
        for (int j = 0; j < originalArray[i].length; j++) {
            System.out.print(originalArray[i][j] + "\t");
        }
        System.out.println();
    }
    return originalArray;
}

标签:sparseArray,int,originalArray,System,算法,数组,数据结构,out
From: https://www.cnblogs.com/wangms821/p/17524376.html

相关文章

  • m基于MOEA算法的无线传感器网络最优部署matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:     2.算法涉及理论知识概要       无线传感器网络(WirelessSensorNetwork,WSN)是一种分布式传感器网络,由大量的无线传感器节点组成,它们可以自组织、自适应、自愈合,通过无线通信协同完成任务。WSN应用广泛,如环境监......
  • m基于MOEA算法的无线传感器网络最优部署matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:2.算法涉及理论知识概要无线传感器网络(WirelessSensorNetwork,WSN)是一种分布式传感器网络,由大量的无线传感器节点组成,它们可以自组织、自适应、自愈合,通过无线通信协同完成任务。WSN应用广泛,如环境监测、农业、医疗等领域。在WSN中,传感......
  • 【算法】基础数据结构
    一、单调栈1.概念满足单调性的栈结构,常用于RMQ问题。2.实现为满足单调性,我们在栈的基础上额外判断以下栈顶元素是否大于/小于当前元素。以下面的序列\(1\;7\;4\;3\;2\;8\)为例,需要求每一个数右边第一个比它大的数。考虑维护单调递减栈,才能保证不会有数没有找到答案便被......
  • 26.数组名和指针(这里为指向数组首元素的指针)区别?
    二者均可通过增减偏移量来访问数组中的元素。数组名不是真正意义上的指针,可以理解为常指针,所以数组名没有自增、自减等操作。当数组名当做形参传递给调用函数后,就失去了原有特性,退化成一般指针,多了自增、自减操作,但sizeof运算符不能再得到原数组的大小了。......
  • 桶排序算法及其Java实现
    桶排序是一种排序算法,它的原理是将数组分到有限数量的桶里,每个桶再个别排序,最后依次把各个桶中的记录列出来。桶排序的效率取决于映射函数的选择和桶的数量。桶排序适用于数据分布比较均匀,或者比较侧重于区间数量的情况。下面是我为你写的博客正文,希望对你有帮助:桶排序算法及其J......
  • 数据挖掘18大算法实现以及其他相关经典DM算法:决策分类,聚类,链接挖掘,关联挖掘,模式挖掘。
    数据挖掘18大算法实现以及其他相关经典DM算法:决策分类,聚类,链接挖掘,关联挖掘,模式挖掘。图算法,搜索算法等算法码源见文末1.算法目录18大DM算法包名目录名算法名AssociationAnalysisDataMining_AprioriApriori-关联规则挖掘算法AssociationAnalysisDataMining_FP......
  • 关于Gin如何在multipart/form-data请求下解析JSON数组
    前言众所周知,在Gin下,如果只是在multipart/form-data请求下解析JSON对象到结构体的话就比较简单。但是如果是要解析JSON数组到对应请求结构体呢?正文举个例子:typeAddItemstruct{IDint`form:"-"` Images[]*multipart.FileHea......
  • 数据结构课后题答案 - XDU_953
    参考书:数据结构与算法分析(第二版)作者:荣政编出版社:西安电子科技大学出版社出版日期:2021年01月01日答案解析: ......
  • 【numpy基础】--数组排序
    numpy数组通常是用于数值计算的多维数组,而排序功能可以快速、准确地对数据进行排序,从而得到更加清晰、易于分析的结果。在数据分析和处理过程中,常常需要对数据进行排序,以便更好地理解和发现其中的规律和趋势。排序会应用在很多场景中,比如:数据分类:将数据按照一定的特征进行分......
  • 【CF1621G】Weighted Increasing Subsequences 题解(优化树状数组)
    CF传送门|LG传送门。优化树状数组+反向处理。Solution发现直接做不好下手。难点主要在求出所有的上升子序列并计算它们分别的贡献。所以需要反向考虑每个单点在什么情况下产生贡献。一个单点会产生多少贡献。一个单点产生贡献的条件很容易得到。一个是在一个上升子序......