分析
稀疏数组一般用在无效数据比有效数据多的情况下,将数组压缩只留下有效的值,避免空间被浪费。
稀疏数组:第一行写总行数、总列数和值的总数
如:
//原来是一个10*10的二维数组(可以看做棋盘)
//0都是无效的值,我们只需要有效的
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 1, 2, 3, 0, 0]
[0, 0, 2, 3, 4, 8, 5, 9, 0, 0]
[0, 0, 0, 0, 0, 0, 2, 0, 0, 0]
[3, 0, 0, 0, 5, 0, 6, 9, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[9, 9, 8, 8, 7, 4, 5, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 3, 2, 0, 0, 0, 0]
//稀疏数组
[10, 10, 26] //总行数、总列数和值的总数
[1, 5, 1] //这个就是代表了第一行(从0开始0-9共10行,列同)第五列值为1
[1, 6, 2]
[1, 7, 3]
[2, 2, 2]
[2, 3, 3]
[2, 4, 4]
[2, 5, 8]
[2, 6, 5]
[2, 7, 9]
[3, 6, 2]
[4, 0, 3]
[4, 4, 5]
[4, 6, 6]
[4, 7, 9]
[6, 0, 9]
[6, 1, 9]
[6, 2, 8]
[6, 3, 8]
[6, 4, 7]
[6, 5, 4]
[6, 6, 5]
[7, 9, 1]
[8, 2, 1]
[8, 3, 1]
[9, 4, 3]
[9, 5, 2]
以下为稀疏数组的实现:
/**
* 实现一个稀疏数组
* @author 鹿上有骨
*
*/
public class Demo12 {
static Scanner sc = new Scanner(System.in);
public static char[][] checkerboard(char[][] str,boolean bool,int l){ //封装棋盘方法
String accept;
for (int i = 0; i < str.length; i++) {
System.out.println("请输入第"+(i+1)+"行元素的值,严格按照你输入的列数(如:5列01202):");
accept = sc.next();
if(accept.length() == l){
str[i] = accept.toCharArray();//将字符串转化为char类型的数组
}else{
System.out.println("列数不对,请重来!");
break;
}
if(i == str.length-1){
bool = true;
}
}
//只有满足条件(全部输入正确才会满足)才会执行
if(bool){
for (int i = 0; i < str.length; i++) {
System.out.println(Arrays.toString(str[i]));
}
}
return str;
}
public static int[][] sparse(char[][] str , int h , int l){ //稀疏数组
int sum = 0;
//检查不为0的值的个数
for (int i = 0; i < str.length; i++) {
for(int j = 0 ; j < str[i].length ; j++){
if((str[i][j]-48) != 0){
sum++;
}
}
}
int in = 1;
int[][] index = new int[sum+1][3];
// 第一行写数组的总行数、总列数和值的总个数
index[0][0] = h;
index[0][1] = l;
index[0][2] = sum;
for (int i = 0; i < str.length; i++) {
for(int j = 0 ; j < str[i].length ; j++){
if((str[i][j]-48) != 0){ //会覆盖,如果一行有多个数的话,所以要另外声明一个变量,来存放索引
index[in][0] = i;
index[in][1] = j;
index[in][2] = str[i][j]-48;
in++;
}
}
}
//将稀疏数组打印出来
for (int i = 0; i < index.length; i++) {
System.out.println(Arrays.toString(index[i]));
}
return index;
}
public static void reduction(int[][] index){ //还原棋盘
int[][] str = new int[index[0][0]][index[0][1]]; //创建一个跟原来一样大小的棋盘
// int xb = 1; //从第二行开始找,但是在二维数组中第二行索引为1
for (int i = 1; i < index.length; i++) {
//如果:index[1][0]第几行
// index[1][1]第几列
// index[1][2]值
//创建的一个int数组,因为默认值为0,索引我们只需要将有数值的填进去就可以了
str[index[i][0]][index[i][1]] = index[i][2];
}
//将原先的棋盘数组打印出来
for (int i = 0; i < str.length; i++) {
System.out.println(Arrays.toString(str[i]));
}
}
public static void main(String[] args) {
System.out.println("请问你想要一个几乘几的表(先行后列):");
int h = sc.nextInt();
int l = sc.nextInt();
char[][] str = new char[h][l];
boolean bool = false;
str = checkerboard(str , bool , l);
System.out.println("=================================");
int[][] index = sparse(str ,h , l);
System.out.println("=================================");
reduction(index);
}
}