经过再次优化和测试,本程序计算速度提升20倍,能在50毫秒左右计算出200*200的随机矩阵
import java.util.ArrayList;
import java.util.Random;
/*需求:对于一个只有0和1的二维矩阵,上下或者左右相邻元素都为1则为一块(斜着不算),求一共有多少取值为1的连续块.如下图:
*
* 0 1 0 1 1 0
* 1 1 0 0 1 1
* 0 0 1 0 0 0
* 1 1 0 0 0 0
*
* 上图中有4块
* */
public class RectPlus01 {
//共享成员变量,存储索引对象One类型的ArraList
static ArrayList<One> list = new ArrayList<One>();
//共享成员变量,矩阵
static int[][] rect=null;
//主函数
public static void main(String[] args) {
function01();
}
//生成指定随机矩阵,逐块提取并计数
private static void function01() {
// 设定矩阵的高和宽
int h = 10;
int w = 10;
// 生成指定随机矩阵int[i][j],并展示在控制台;将元素值为1的元素存入List,并展示在控制台
Random rdm = new Random();
rect = new int[h][w];
System.out.println("随机生成矩阵如下图:");
for (int i = 0; i < rect.length; i++) {
for (int j = 0; j < rect[i].length; j++) {
int k = rdm.nextInt(2);
rect[i][j] = k;
System.out.print(" " + rect[i][j]);
// 将数值为1的元素的对象加入到ArrayList
if (k == 1) {
list.add(new One(i, j));
}
}
System.out.println();
}
System.out.println("开始进行计算");
// 开始计时
long time = System.currentTimeMillis();
// 定义count用于统计块数
int count = 0;
// 循环,每排除一块循环一次
while (list.size() != 0) {
// list只剩一个元素时无需再进行判断
if (list.size() == 1) {
count++;
break;
}
One o = list.get(0);
// 调用方法,将同一个块中的所有对象从list中删除
delete(o);
count++;
}
// 输出块数
// System.out.println("计算结束");
System.out.println("该矩阵中,共有" + count + "块");
// 输出计时结果
System.out.println("计算用时(ms):" + (System.currentTimeMillis() - time));
}
// 将与o所在的块中的所有对象从list中删除
private static void delete(One o) {
// 分别判断o坐标对应的数组元素的上下左右的邻元素是否是1(避开索引越界),如果是1就将该邻元素的坐标对象删除,递归;
int i = o.i;
int j = o.j;
// 修改o坐标对应的数组元素的值(避免递归时反复判断相邻元素)
rect[i][j] = 4;
// 先将o移除,使得后续的递归在移除元素时更快(元素越少越快)
list.remove(o);
if (i < rect.length - 1 && rect[i + 1][j] == 1) {
One oD = new One(i + 1, j);
delete(oD);
}
if (i > 0 && rect[i - 1][j] == 1) {
One oU = new One(i - 1, j);
delete(oU);
}
if (j < rect[i].length - 1 && rect[i][j + 1] == 1) {
One oR = new One(i, j + 1);
delete(oR);
}
if (j > 0 && rect[i][j - 1] == 1) {
One oL = new One(i, j - 1);
delete(oL);
}
}
}
// 定义内部类,将坐标对象封装在One类
class One {
// 横坐标
int i;
// 纵坐标
int j;
public One(int i, int j) {
super();
this.i = i;
this.j = j;
}
public String toString() {
return "(" + this.i + "," + this.j + ")";
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + i;
result = prime * result + j;
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
One other = (One) obj;
if (i != other.i)
return false;
if (j != other.j)
return false;
return true;
}
}