Java基础3——检查数独的解决方案是否正确,两种方法

/**
数独是一个9x9网格,被分为9个3x3的块。
将1~9输入格子里,使每行每列及每块都包含1~9九个数字。
检查数独的解决方案是否正确有两种方法:
方法1:检查是否每行每列每块都有1~9;
方法2:检查每个单元格,数字必须是1~9,且该数字在每行每列每块都是唯一的。
 */

/*有效的数独
9 6 3 1 7 4 2 5 8
1 7 8 3 2 5 6 4 9
2 5 4 6 8 9 7 3 1
8 2 1 4 3 7 5 9 6
4 9 6 8 5 2 3 1 7
7 3 5 9 6 1 8 2 4
5 8 9 7 1 3 4 6 2
3 1 7 2 4 6 9 8 5
6 4 2 5 9 8 1 7 3
 */

import java.util.Scanner;

public class CheckSudokuSolution {

	public static void main(String[] args) {
		//读取数独解决方案
		int[][] grid=readASolution();
		//打印结果
		System.out.println("方法1:"+(isValid1(grid)?"Valid Solution":
			"Invalid Solution"));
		System.out.println("方法2:"+(isValid2(grid)?"Valid Solution":
			"Invalid Solution"));
	}
	
	//从控制台读取数独解决方案
	public static int[][] readASolution(){
		Scanner input=new Scanner(System.in);
		
		System.out.println("Enter a Sudoku puzzle solution:");
		int[][] grid=new int[9][9];
		for(int i=0;i<9;i++)
			for(int j=0;j<9;j++)
				grid[i][j]=input.nextInt();
		return grid;
	}
	
	//方法1:

	//将每列数字保存至一个二维数组,通过将横纵坐标交换
	public static int[][] column(int[][] grid){
		int[][] c=new int[9][9];
		for(int i=0;i<9;i++)
			for(int j=0;j<9;j++)
				c[i][j]=grid[j][i];
		return c;
	}
	
	//将每块的数字保存至一个二维数组
	public static int[][] block(int[][] grid){
		int[][] b=new int[9][9];
		for(int i=0;i<9;i++)
			for(int j=0;j<9;j++){
				//将数独从左至右从上至下分为9块,求该单元格属于第几块,将该块数字保存至b第几行
				int rowOfB=i/3*3+j/3;
				//每块有9个数字,求该数字属于第几个,保存至b第几列
				int columnOfB=i%3*3+j%3;
				b[rowOfB][columnOfB]=grid[i][j];
			}
		
		/*检查块数字转变为二维数组的每一行,是否正确
		for(int row=0;row<9;row++){
			for(int col=0;col<9;col++)
				System.out.print(b[row][col]+" ");
			System.out.println( );
		}
		*/	
		 
		return b;
	}
	
	//检查一个长度为9的数组是否只包含1~9
	public static boolean checkNumber1(int[] matrix){
		//声明一个包含9个元素的数组,每个元素都初始化为0
		int[] temp=new int[9];
		for(int i=0;i<9;i++)
			temp[i]=0;
		
		for(int i=0;i<9;i++){
		//检查matrix的每个元素是否在1~9之间,如果是,则将temp的第matrix[i]-1个数字置为1
		//当且仅当temp每个数字均为1时,matrix的元素包含1~9的每个数字
			if(matrix[i]>0&&matrix[i]<10)
				temp[matrix[i]-1]=1;
		}
		
		for(int i=0;i<9;i++){
		//如果temp不全为1,则返回false
			if(temp[i]!=1)
				return false;
		}
		return true;
	}
	
	//检查一个9*9的二维数组每行是否只含1~9
	public static boolean checkNumber2(int[][] secMatrix){
		for(int i =0;i<9;i++)
			if(!checkNumber1(secMatrix[i])) 
				return false;
		return true;
	}
	
	public static boolean isValid1(int[][] grid){
		//检查每行数字是否都有1~9
		if(!checkNumber2(grid)) return false;
		
		//检查每列数字是否都有1~9
		int[][] columnMatrix=column(grid);
		if(!checkNumber2(columnMatrix)) return false;
		
		//检查每块数字是否都有1~9
		int[][] blockMatrix=block(grid);
		if(!checkNumber2(blockMatrix)) return false;
		
		return true;
	}
	
	//方法2:
	public static boolean isValid2(int[][] grid){
		//依次检查每个单元格的数字是否在1~9之间,及该数字在每行每列每块是否唯一
		for(int i=0;i<9;i++)
			for(int j=0;j<9;j++)
				if(grid[i][j]<1||grid[i][j]>9||!isOnly(grid,i,j))
					return false;
		return true;
	}
	
	public static boolean isOnly(int[][] grid,int i,int j){
		//检查每行中该数字是否唯一
		for(int col=0;col<9;col++)
			if(col!=j&&grid[i][col]==grid[i][j])
				return false;
		
		//检查每列中该数字是否唯一
		for(int row=0;row<9;row++)
			if(row!=i&&grid[row][j]==grid[i][j])
				return false;
		
		//检查每块中该数字是否唯一
		for(int row=i/3*3;row<i/3*3+3;row++)
			for(int col=j/3*3;col<j/3*3+3;col++){
				if(row!=i&&col!=j&&grid[row][col]==grid[i][j])
					return false;
			}
		
		return true;
	}
}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值