import java.util.*;
public class Sudoku {
// 方案數量
public static int caseCount;
// sudoku 二位數組
public static int[][] chessboard=new int[9][9];
// 初始化二位數組
public static void init(){
chessboard = new int[][]{
{7,0,0,0,0,4,0,2,0},
{0,9,0,0,0,0,3,0,0},
{0,0,0,0,0,6,0,0,8},
{0,8,0,9,0,0,0,0,0},
{0,3,5,0,0,0,0,0,9},
{0,0,0,0,7,2,0,4,0},
{0,0,9,5,2,0,0,0,0},
{0,0,0,0,0,0,8,6,7},
{1,0,0,3,0,0,0,0,0}
};
// 靜態Int型數據默認是0,這裏初始化方便邏輯書寫
caseCount = 0;
}
// 查找可用集合
public static Set<Integer> canUse(int row, int col){
Set<Integer> set = new HashSet<>(Arrays.asList(1,2,3,4,5,6,7,8,9));
// 排除行上數據
for (int index = 0;index <=8; index++){
set.remove(chessboard[row][index]);
}
// 排除列上數據
for (int index = 0;index <=8; index++){
set.remove(chessboard[index][col]);
}
// 排除方格內的數據
int xxx = row/3;
int yyy = col/3;
for (int y = yyy*3; y<(yyy+1)*3; y++){
for (int x = xxx*3; x<(xxx+1)*3; x++){
set.remove(chessboard[x][y]);
}
}
return set;
}
// 查找下一個
public static int[] next(int row, int col){
// 某行還沒走到盡頭
if (col<8){
return new int[]{row,++col};
}
// 如果某行走到盡頭
if (col == 8 && row<8){
return new int[]{++row,0};
}
// 如果行和列都走到盡頭,返回null
return null;
}
// 打印結果
public static void printResult(){
for (int row = 0; row<=8; row++){
for (int col = 0; col<=8; col++){
System.out.print(chessboard[row][col] + " ");
if ((col+1)%3==0){
System.out.print(" ");
}
}
System.out.println();
if ((row+1)%3==0){
System.out.println();
}
}
}
// 添加數字
public static void fillNumber(int row, int col){
// 當前值爲空位的時候
if (chessboard[row][col] == 0){
// 先查找所有可能
Set<Integer> canUseSet = canUse(row,col);
List<Integer> list = new ArrayList<>(canUseSet);
for (Integer integer:list){
chessboard[row][col] = integer;
// 查找下一個
int[] nextPosition = next(row, col);
if (Objects.isNull(nextPosition) || nextPosition.length == 0){
//可以輸出一個結果
System.out.println("結果"+(++caseCount)+":");
printResult();
}else {
//查找下一個
int newRow = nextPosition[0];
int newCol = nextPosition[1];
fillNumber(newRow,newCol);
}
chessboard[row][col] = 0;
}
}else {
int[] nextPosition = next(row, col);
if (Objects.isNull(nextPosition) || nextPosition.length == 0){
//可以輸出一個結果
System.out.println("結果"+(++caseCount)+":");
printResult();
}else {
//查找下一個
int newRow = nextPosition[0];
int newCol = nextPosition[1];
fillNumber(newRow,newCol);
}
}
}
public static void main(String[] args) {
// 初始化
init();
System.out.println("原始數據:");
printResult();
System.out.println("結果集:");
fillNumber(0,0);
}
}
【小DEMO】回溯法破解數獨
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.