package algothrim;
import java.util.ArrayList;
import java.util.List;
public class Sudoku {
private char[][] board;
private boolean[][] line = new boolean[9][9];
private boolean[][] column = new boolean[9][9];
private boolean[][][] block = new boolean[3][3][9];
private List<int[]> spaces = new ArrayList<>();
private int length;
public Sudoku(char[][] board){
this.board = board;
}
/**
* 将待填入的数的位置置于集合spaces中。
* 将给定数在同一行,同一列,同一个单元格设置为不可再次出现。
*/
public void traverse(){
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if(board[i][j] == '.'){
spaces.add(new int[]{i,j});
}else {
int digit = board[i][j] - '0' - 1;
line[i][digit] = column[j][digit] = block[i /3][j / 3][digit] = true;
}
}
}
length = spaces.size();
}
/**
* 判断这个数在这个位置能否出现出现
* @param index 位置
* @param value 填入这个位置的数
* @return 能填入返回true,否则返回false
*/
public boolean reasonable(int index, int value){
int i = spaces.get(index)[0];
int j = spaces.get(index)[1];
int digit = value - 1;
if ( line[i][digit] ){
return false;
}
if(column[j][digit]){
return false;
}
if ( block[i /3][j / 3][digit] ){
return false;
}
return true;
}
/**
* 将参数的值在同一行,同一列,同一个单元格设置为不可再次出现。
* @param index 位置
* @param value 值
*/
public void set (int index, int value){
int i = spaces.get(index)[0];
int j = spaces.get(index)[1];
int digit = value - 1;
line[i][digit] = true;
column[j][digit] = true;
block[i /3][j / 3][digit] = true;
}
/**
* 将参数的值在同一行,同一列,同一个单元格设置为可再次出现。
* @param index 位置
* @param value 值
*/
public void back (int index, int value){
int i = spaces.get(index)[0];
int j = spaces.get(index)[1];
int digit = value - 1;
line[i][digit] = false;
column[j][digit] = false;
block[i /3][j / 3][digit] = false;
}
/**
* 将盘上的相应位置的数设置为可以填入的数
* @param index 位置
* @param value 填入的数
*/
public void setBoard(int index, int value){
int i = spaces.get(index)[0];
int j = spaces.get(index)[1];
board[i][j] = (char)('0' + value);
}
/**
* 利用递归回溯,求出给定位置可以输入的数
* @param index 位置
* @return 存在返回true
*/
public boolean recursiveBacktracking(int index){
if(index >= length){
return true;
}else{
for (int i = 1; i <= 9; i++) {
if ( reasonable(index, i) ){
set(index, i);
if ( recursiveBacktracking(index + 1)){
setBoard(index,i);
return true;
}else{
back(index, i);
}
}
}
return false;
}
}
/**
* 执行程序
*/
public void start(){
traverse();
recursiveBacktracking(0);
System.out.println();
}
}