性能提升版:对于一个只有0和1的二维矩阵,上下或者左右相邻元素都为1则为一块(斜着不算),求一共有多少取值为1的连续块

经过再次优化和测试,本程序计算速度提升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;
	}
}

猜你喜欢

转载自blog.csdn.net/hssykey/article/details/81410026