这是一个可以根据现有数独的一部分,然后将整个数独补全的程序。大概思路就是采用回溯算法,然后每个点对每个数进行尝试,如果可以,那么继续向前尝试,如果当前格子放入1-9 的所有数字都不行,那么说明前一个,或者几个都放错了,然后回溯到之前,即退回到上一个格子的情况,进行重新尝试,如果失败,那么继续这个过程。直到数独被填满。以下是代码。
package com.anzhuo.util.sd;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class ShuduB {
/**
* 校驗是否成功
* @param targetArray
* @return
*/
private static boolean checkStatus(int[][] targetArray) {
boolean flag = true;
w:
for (int i = 0; i < 9; i++) {
List<Integer> col = new ArrayList<>();
for (int k = 0; k < 9; k++) {
if (targetArray[k][i] != 0 && col.indexOf(targetArray[k][i]) != -1) {
flag = false;
break w;
}
col.add(targetArray[k][i]);
}
List<Integer> hang = new ArrayList<>();
for (int j = 0; j < 9; j++) {
if (targetArray[i][j] != 0 && hang.indexOf(targetArray[i][j]) != -1) {
flag = false;
break w;
}
hang.add(targetArray[i][j]);
}
for (int x = 0; x < 9; x++) {
List<Integer> block = new ArrayList<>();
int i1 = i / 3;
int j2 = x / 3;
int i3 = i1 * 3;
int j3 = j2 * 3;
judge:
for (int v = 0; v < 3; v++) {
int currentX = i3 + v;
for (int t = 0; t < 3; t++) {
int startY = j3 + t;
if(currentX == i && startY== x){
continue ;
}
if (targetArray[i][x] != 0 && block.indexOf(targetArray[i][x]) != -1) {
flag = false;
break w;
}
block.add(targetArray[currentX][startY]);
}
}
}
}
return flag;
}
private static void getShudu(int [][] array){
putOneNum(array,null,new Stack<SdPoint>());
}
private static SdPoint getFreeBlock(int [][] array){
for(int i = 0;i<9;i++){
for(int j =0 ;j<9;j++){
if(array[i][j] == 0){
SdPoint sdPoint = new SdPoint();
sdPoint.setX(i);
sdPoint.setY(j);
return sdPoint ;
}
}
}
return null ;
}
private static void putOneNum(int [][] array, SdPoint lastPoint, Stack<SdPoint> stack){
System.out.println("当前填充了"+stack.size());
boolean flag = true ;
SdPoint freeBlock = getFreeBlock(array);
if( freeBlock == null){
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(array[i][j] + ",");
}
System.out.println("");
}
return;
}else{
// 格子需要装填
if(lastPoint != null){
// if(stack.size() == 0){
//
//
// System.out.println("sssssss");
// System.out.println(lastPoint.getValue());
// }
for(int x =1 ;x<10 ;x++){
if(x <= lastPoint.getValue()){
continue;
}
array[freeBlock.getX()][freeBlock.getY()] = x ;
if(checkStatus(array)){
freeBlock.setValue(x);
stack.push(freeBlock);
putOneNum(array,null,stack);
flag = false ;
break;
}
}
if(flag){
array[freeBlock.getX()][freeBlock.getY()] = 0 ;
SdPoint pop = stack.pop();
array[pop.getX()][pop.getY()] = 0 ;
putOneNum(array,pop,stack);
}
}else {
for(int x =1 ;x<10 ;x++){
array[freeBlock.getX()][freeBlock.getY()] = x ;
if(checkStatus(array)){
freeBlock.setValue(x);
stack.push(freeBlock);
putOneNum(array,null,stack);
flag = false ;
break;
}
}
if(flag){
array[freeBlock.getX()][freeBlock.getY()] = 0 ;
// 回退
SdPoint pop = stack.pop();
array[pop.getX()][pop.getY()] = 0 ;
putOneNum(array,pop,stack);
}
}
}
}
public static void main(String[] args) {
int[][] integers = {
{0, 1, 0, 0, 0, 8, 4, 0, 7},
{9, 5, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 8, 0, 1, 0, 0, 0, 0},
{0, 8, 2, 0, 0, 0, 0, 0, 0},
{7, 0, 0, 4, 0, 6, 0, 0, 8},
{0, 0, 0, 0, 0, 0, 6, 2, 0},
{0, 0, 0, 0, 5, 0, 7, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 8, 2},
{5, 0, 3, 2, 0, 0, 0, 1, 0},
};
getShudu(integers);
}
}