今天和你聊聊稀疏数组!
前言1:稀疏数组出现的原因!
假设我们在玩围棋,棋盘是11*11,用0表示空位,1表示黑棋,2表示蓝棋。那用普通数组储存是不是会有很多0在占用空位,使得内存增加。所以当一个数组中有很多0的时候,为节省内存稀疏数组就应运而生了。
前言2:什么是稀疏数组?
稀疏数组也是数组的一种,行数代表普通二维数组中的非零值个数,我称之为有效数,列数固定是三列。第一列是有效数的行,第二列是有效数的列,第三列就是有效数的值。用每一行来确定一个有效值对应的坐标和值。
1.例子分析
-
假设棋局如下,如何用普通数组和稀疏数组进行描述?
-
普通二维数组和稀疏数组表示结果的比较。
这对比还得了,吓得我赶紧去学稀疏数组了!
2. 解题过程
1. 用普通数组记录。
首先我们应该创建一个11*11的数组,然后往里面赋值,这个应该很简单。
// 创建一个11*11的二维数组,用0表示没有棋子,用1表示黑棋,用2表示白棋
int[][] arrys = new int[11][11];
arrys[1][2] = 1;
arrys[2][3] = 2;
2. 打印二维数组元素
for (int[] arry : arrys) {//遍历行
for (int i : arry) {//遍历列
System.out.print(i + " ");
}
System.out.println();//遍历完一行之后就换行
}
System.out.println("==============================");//可以选择输出分割线表示美观
3. 用稀疏数组表示
-
遍历普通数组元素的非零值个数
//遍历有效值个数 int sum = 0;//用于计算元素的非零值个数 for (int i = 0; i < 11; i++) { for (int j = 0; j < 11; j++) { if (arrys[i][j]!= 0){ sum ++; } } }
-
创建稀疏数组并给首行,即给第0行赋值
//创建稀疏数组并给首行,即使第0行赋值 int[][] arr = new int[sum+1][3]; arr[0][0] = 11; arr[0][1] = 11; arr[0][2] = sum;
-
给稀疏数组其他行赋值,列数是固定的。
//遍历二维数组,将值存放到稀疏数组中 int count = 0; for (int i = 0; i < arrys.length; i++) { for (int j = 0; j < arrys[i].length; j++) { if (arrys[i][j] != 0 ){ count ++; arr[count][0] = i; arr[count][1] = j; arr[count][2] = arrys[i][j]; } } }
4. 打印稀疏数组
//输出稀疏数组
System.out.println("输出稀疏数组:");
System.out.println("行" + "\t" + "列" + "\t" + "有效数字");
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < 3 ; j++) {
System.out.print(arr[i][j] + "\t");
}
System.out.println();
}
到这里我们其实已经把这题解出来了,但是我们能不能把数组还原回去呢?答案是:当然能!
3.还原数组
-
读取原来数组的长和宽
//读取稀疏数组还原原来数组的长和宽 int[][] arry = new int[arr[0][0]][arr[0][1]];
-
还原其中的值
//还原其中的值 for (int i = 1; i < arr.length ; i++) { arry[arr[i][0]][arr[i][1]] = arr[i][2]; }
-
打印数组
//打印还原后的稀疏数组 System.out.println("打印还原后的稀疏数组:"); for (int[] arry1 : arry) { for (int i : arry1) { System.out.print( i + " "); } System.out.println(); } System.out.println("==============================");
完了吗?还没完,这样麻烦对不对,那我们将它们打包成方法吧
4. 整理后代码
/**
* 二维数组和稀疏数组
*/
public class Demon3 {
public static void main(String[] args) {
// 创建一个11*11的二维数组,用0表示没有棋子,用1表示黑棋,用2表示白棋
int m = 11, n = 11;//用来设置棋盘的大小
int[][] arrys = new int[m][n];
arrys[1][2] = 1;
arrys[2][3] = 2;
PrintArry(arrys);//打印二维数组
int[][] arr = RewordArry(m,n,arrys);//将二维数组转换成一个稀疏数组并返回,用一个数组接收
PrintEspecialArry(arr);//打印稀疏数组
int[][] arr1 = ReturnArry(arr);//将稀疏数组还原为一个二维数组,并用一个数组接收
PrintArry(arr1);//打印二维数组
PrintArry(ReturnArry(arr));//也可以直接调用打印方法接收对象
}
/**
* 打印二维数组的方法
* @param arry1
*/
public static void PrintArry ( int[][] arry1){//传入一个二维数组
System.out.println("二维数组如下");
for (int[] arry : arry1) {//遍历数组的行
for (int i : arry) {//遍历数组的列
System.out.print(i + " ");
}
System.out.println();//遍历完一行后换行
}
System.out.println("==============================");//输出分割线让界面美观
}
/**
* 转换成稀疏数组的方法
*
* @param m
* @param n
* @param arry2
* @return
*/
public static int[][] RewordArry ( int m, int n, int[][] arry2){
//遍历有效值个数
int sum = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (arry2[i][j] != 0) {
sum++;
}
}
}
//转换为稀疏数组
int[][] arr = new int[sum + 1][3];
arr[0][0] = m;
arr[0][1] = n;
arr[0][2] = sum;
//遍历二维数组,将值存放到稀疏数组中
int count = 0;
for (int i = 0; i < arry2.length; i++) {
for (int j = 0; j < arry2[i].length; j++) {
if (arry2[i][j] != 0) {
count++;
arr[count][0] = i;
arr[count][1] = j;
arr[count][2] = arry2[i][j];
}
}
}
return arr;
}
/**
* 打印稀疏数组
* @param arry3
*/
public static void PrintEspecialArry ( int[][] arry3){
System.out.println("输出稀疏数组:");
System.out.println("行" + "\t" + "列" + "\t" + "有效数字");
for (int i = 0; i < arry3.length; i++) {
for (int j = 0; j < 3; j++) {//稀疏数组固定长度为三
System.out.print(arry3[i][j] + "\t");
}
System.out.println();
}
System.out.println("==============================");
}
/**
* 还原数组
* @param arry4
* @return
*/
public static int[][] ReturnArry ( int[][] arry4){
//读取稀疏数组还原原来数组的长和宽
int[][] arry = new int[arry4[0][0]][arry4[0][1]];
//还原其中的值
for (int i = 1; i < arry4.length; i++) {
arry[arry4[i][0]][arry4[i][1]] = arry4[i][2];
}
return arry;
}
}
全码终!
彩蛋之送你一个有趣的注释:码农必备
/***
* _ooOoo_
* o8888888o
* 88" . "88
* (| -_- |)
* O\ = /O
* ____/`---'\____
* . ' \\| |// `.
* / \\||| : |||// \
* / _||||| -:- |||||- \
* | | \\\ - /// | |
* | \_| ''\---/'' | |
* \ .-\__ `-` ___/-. /
* ___`. .' /--.--\ `. . __
* ."" '< `.___\_<|>_/___.' >'"".
* | | : `- \`.;`\ _ /`;.`/ - ` : | |
* \ \ `-. \_ __\ /__ _/ .-` / /
* ======`-.____`-.___\_____/___.-`____.-'======
* `=---='
*
* .............................................
* 佛祖保佑 永无BUG
*/
大家晚安,头发重要!