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

修改了块的提取逻辑,简化了块的提取过程,使得性能提升很大,可以很快地计算出200*200的矩阵

import java.util.ArrayList;
import java.util.HashSet;
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 TestPlus {

	public static void main(String[] args) {
		function01();
	}
	/*思路:
	 * 1.先生成指定矩阵int[4][6],随机添加0,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
	 *2.建立内部类,将每个值为1的元素包装为一个One对象(包含两个属性,int i和int j,重写toString),将这些对象存入ArrayList<One> list;
	 *3.定义计数count,当list中有元素时,进行循环:{调用方法delete,将属于同一个块的One对象从list中删除,并计数count++};
	 *4.方法delete():递归{将某One对象所在块内的所有One对象从list中移除-----只对某One对象代表的数组元素的上下左右的数组元素进行判断,使得性能极大提升}
	 * 
	 * */
	private static void function01() {
		//建立存储索引对象One类型的ArraList
				ArrayList<One> list=new ArrayList<One>();
				//生成指定随机矩阵int[i][j],并展示在控制台;将元素值为1的元素存入List,并展示在控制台
				Random rdm=new Random();
				int[][] cube=new int[10][10];
				System.out.println("随机生成矩阵如下图:");
				for (int i = 0; i < cube.length; i++) {
					for (int j = 0; j < cube[i].length; j++) {
						int k=rdm.nextInt(2);
						cube[i][j]=k;
						System.out.print(" "+cube[i][j]);
						//将数值为1的元素的对象加入到ArrayList
						if(k==1){
							list.add(new One(i,j));
						}
					}
					System.out.println();
				}
				System.out.println("开始进行计算");
				//定义count用于统计块数
				int count=0;
				//循环,每排除一块循环一次
				while(list.size()!=0){
					if(list.size()==1){
						count++;
						break;
					}else{
						One o=list.get(0);
						//调用方法,将同一个块中的所有对象从list中删除
						delete(o,list,cube);
						count++;
					}
				}
				System.out.println("该矩阵中,共有"+count+"块");
	}
	//将与o所在的块中的所有对象从list中删除
		private static void delete(One o,ArrayList<One> list,int[][] cube){
			//修改o坐标对应的数组元素的值(避免递归时反复判断相邻元素)
			//分别判断o坐标对应的数组元素的上下左右的邻元素是否是1(避开索引越界),如果是1就将该邻元素的坐标对象删除,递归;如果不是1就向下继续
			int i=o.i;
			int j=o.j;
			cube[i][j]=4;
			if(i<cube.length-1&&cube[i+1][j]==1){
				list.remove(new One(i+1,j));
				delete(new One(i+1,j),list,cube);
			}
			if(i>0&&cube[i-1][j]==1){
				list.remove(new One(i-1,j));
				delete(new One(i-1,j),list,cube);
			}
			if(j<cube[i].length-1&&cube[i][j+1]==1){
				list.remove(new One(i,j+1));
				delete(new One(i,j+1),list,cube);
			}
			if(j>0&&cube[i][j-1]==1){
				list.remove(new One(i,j-1));
				delete(new One(i,j-1),list,cube);
			}
			list.remove(o);
		}
	}
//定义内部类,将坐标对象封装在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/81380308