Java实现9x9数独网格行列有效性校验问题咨询
实现步骤
第一步:补充Square3x3类的取值方法
因为Square3x3类的mat成员是私有属性,Sudoku类无法直接访问,首先需要给Square3x3新增获取指定位置数值的方法,同时补充你代码中缺失的常量定义:
public class Square3x3 { // 补充缺失的常量定义 private static final int NUM_OF_ROWS = 3; private static final int NUM_OF_COLS = 3; private int[][] mat = new int [3][3]; // 新增取值方法 public int getValue(int row, int col) { if(row <0 || row >= NUM_OF_ROWS || col <0 || col >= NUM_OF_COLS) { throw new IllegalArgumentException("行列参数必须在0到2之间"); } return mat[row][col]; } // 你原有allThere方法保留 public boolean allThere(){ int[] options = {1,2,3,4,5,6,7,8,9}; for (int i = 0 ; i < NUM_OF_ROWS; i++){ for(int j =0 ; j < NUM_OF_COLS; j++){ for (int k = 0; k < options.length; k++){ if(mat[i][j] == options[k]) { options[k] = -1; break; } } } } for (int num : options) { if(num != -1) return false; } return true; } }
第二步:在Sudoku类中实现行、列校验逻辑
数独的每行对应3个横向相邻Square3x3块的同一内部行,每列对应3个纵向相邻Square3x3块的同一内部列,通过布尔数组标记数字是否重复出现即可完成校验:
public class Sudoku { private Square3x3[][] grid9x9 = new Square3x3[3][3]; // 校验所有行有效 public boolean areAllRowsValid() { // 遍历数独的9行 for (int sudokuRow = 0; sudokuRow < 9; sudokuRow++) { boolean[] appeared = new boolean[10]; // 下标0闲置,1~9对应数字1~9 int blockRow = sudokuRow / 3; // 当前行所属的3x3块的行索引 int innerRow = sudokuRow % 3; // 当前行在3x3块内部的行索引 // 遍历横向的3个3x3块 for (int blockCol = 0; blockCol < 3; blockCol++) { Square3x3 currentBlock = grid9x9[blockRow][blockCol]; // 遍历块内对应行的3个元素 for (int innerCol = 0; innerCol < 3; innerCol++) { int num = currentBlock.getValue(innerRow, innerCol); // 数字不合法或重复出现,行无效 if (num < 1 || num >9 || appeared[num]) { return false; } appeared[num] = true; } } // 校验当前行是否包含1~9所有数字 for (int i = 1; i <=9; i++) { if(!appeared[i]) return false; } } return true; } // 校验所有列有效 public boolean areAllColsValid() { // 遍历数独的9列 for (int sudokuCol = 0; sudokuCol <9; sudokuCol++) { boolean[] appeared = new boolean[10]; int blockCol = sudokuCol /3; // 当前列所属的3x3块的列索引 int innerCol = sudokuCol %3; // 当前列在3x3块内部的列索引 // 遍历纵向的3个3x3块 for (int blockRow =0; blockRow <3; blockRow++) { Square3x3 currentBlock = grid9x9[blockRow][blockCol]; // 遍历块内对应列的3个元素 for (int innerRow =0; innerRow <3; innerRow++) { int num = currentBlock.getValue(innerRow, innerCol); if (num <1 || num>9 || appeared[num]) { return false; } appeared[num] = true; } } // 校验当前列是否包含1~9所有数字 for (int i=1; i<=9; i++) { if(!appeared[i]) return false; } } return true; } // 可选:完整数独有效性校验(块+行+列都合法) public boolean isSudokuValid() { // 先校验所有3x3块合法 for (int i=0; i<3; i++) { for(int j=0; j<3; j++) { if(!grid9x9[i][j].allThere()) { return false; } } } // 校验行和列合法 return areAllRowsValid() && areAllColsValid(); } }
内容的提问来源于stack exchange,提问作者test_junkie123
相关产品推荐
相关产品推荐

