Java数据结构与算法-稀疏矩阵代码实现

稀疏数组与原数组相互转换以及应用场景

Sparsearray的学习目标
  1. 基本介绍
  2. 存储方式
  3. 应用场景
  4. 代码实现
  5. 注意与总结
一,基本介绍
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
二,存储方式
(1)首先稀疏数组是一个三元组,分别存储行,列,值
(2)第一行特殊,用来记录原数组的行数,列数,非零元素数;
(3)从第二行开始把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模

图解如下:
图解

三,应用场景

1,需求:记录五子棋的下棋位置,具有存盘和取盘的功能。
应用需求
分析下我们该如何解决问题?
思路如下:
思路
(1)首先先创建一个二维数组,然后用1和2分别表示白棋和黑棋,0表示空,然后存储相应的位置。
(2)然后用稀疏数组进行存储原数组
(3)利用IO流进行本地的读写操作
(4)还原本地读出来的数组

四,代码实现
package com.atxiaopeng.sparsearry;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.zip.InflaterInputStream;

public class ParseArry {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		
		//1,创建一个二维数组进行存储数据,0代表没有棋子,1代表白色棋子,2代表黑色棋子
		int chessarr1 [][] = new int [9][9];
		chessarr1 [1][2] = 1;
		chessarr1 [2][3] = 2;
		
		//2,遍历数组元素
		int sum = 0;
		System.out.println("===========原始数组==========");
		for (int i = 0; i < chessarr1.length; i++) {
			for (int j = 0; j < chessarr1[i].length; j++) {
				if (chessarr1[i][j]!=0) {
					sum++;
				}
				System.out.print(chessarr1[i][j]+" ");
			}
			System.out.println();
		}
		
		
		//3,创建稀疏数组,并且把非零元素存进去
		int parsearr[][] = new int [sum+1][3];
		parsearr[0][0] = chessarr1.length;
		parsearr[0][1] = chessarr1[0].length;
		parsearr[0][2] = sum;
		int count = 1;
		for (int i = 0; i < chessarr1.length; i++) {
			for (int j = 0; j < chessarr1[i].length; j++) {
				if (chessarr1[i][j]!=0) {
					parsearr [count] [0] = i;
					parsearr [count] [1] = j;
					parsearr [count] [2] = chessarr1[i][j];
					count++;
				}
			}
		}
		
		System.out.println("=========转稀疏矩阵成功==========");
		
		//4,打印稀疏数组
		for (int i = 0; i < parsearr.length; i++) {
			System.out.println(parsearr[i][0]+" "+parsearr[i][1]+" "+parsearr[i][2]);
		}
		
		//6,从稀疏数组转换为原数组
		int chessarr3 [][] = new int [parsearr[0][0]] [parsearr[0][1]];
		for (int i = 1; i < parsearr.length; i++) {
			chessarr3[parsearr[i][0]] [parsearr[i][1]] = parsearr[i][2];
		}
		//7,打印恢复后的数组
		System.out.println("===========恢复成原数组==========");
		for (int i = 0; i < chessarr3.length; i++) {
			for (int j = 0; j < chessarr3[i].length; j++) {
				System.out.print(chessarr3[i][j]+" ");
			}
			System.out.println();
		}
		
		
		//8,把稀疏数组存取到本地文件
		System.out.println("正在写入......");
		File sparsearry = new File("F:\\sparsearry.txt");
		FileOutputStream fs = new FileOutputStream(sparsearry);
		OutputStreamWriter os = new OutputStreamWriter(fs,"utf-8");
		for (int i = 0; i < parsearr.length; i++) {
			for (int j = 0; j < parsearr[i].length; j++) {
				os.write(String.valueOf(parsearr[i][j]));
				if (i==(parsearr.length)-1&&j==(parsearr[(parsearr.length)-1].length)-1) {
					
				}else {
					os.write(",");
				}
				
			}
		}

		os.close();
		fs.close();
		System.out.println("===========写入成功==========");
		
		//9,读取本地的稀疏数组
		System.out.println("正在读取......");
		FileInputStream in = new FileInputStream("F://sparsearry.txt");
		
		InputStreamReader inread = new InputStreamReader(in,"utf-8");
		
		StringBuffer sb = new StringBuffer();
		while (inread.ready()) {
			sb.append((char)inread.read());
			
		}
		inread.close();
		in.close();
		System.out.println("===========读取成功==========");
		System.out.println(sb);
		String str[] = sb.toString().split(",");//注意要把它转换为string对象进行分割
		
//		for(String string : str) {
//			System.out.print(string);
//		} 输出分割后的数组
		
		System.out.println("=========稀疏矩阵恢复=========");
		int recoverarr[][] = new int [str.length/3][3];
		int c = 0;
		for (int i = 0; i < recoverarr.length; i++) {
			for (int j = 0; j < recoverarr[i].length; j++) {
				if (c<=str.length-1) {
					recoverarr[i][j]=Integer.parseInt(str[c]);
					c++;
				}
				
			}
		}
		for (int i = 0; i < recoverarr.length; i++) {
			System.out.println(recoverarr[i][0]+" "+recoverarr[i][1]+" "+recoverarr[i][2]);
		}
		
	}

}

以上是我写的代码过程,如有错误欢迎指正。

五,注意与总结
  • 稀疏数组保存到本地时是字符串,读取出来需要进行分割
  • 然后把分割后的字符转换为int类型进行恢复数组
  • IO流操作完成后一定要关闭
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值