用程序解数独,发现数独是个好东西,让我收获颇多

最近在本站看到某篇关于解数独的程序的博客,于是下载后尝试了下,发现有些数独是可以解的,但当我把下面这个数独放进去后,它不能够给我解出来:

{8,0,0,0,0,0,0,0,0},
{0,0,3,6,0,0,0,0,0},
{0,7,0,0,9,0,2,0,0},
{0,5,0,0,0,7,0,0,0},
{0,0,0,0,4,5,7,0,0},
{0,0,0,1,0,0,0,3,0},
{0,0,1,0,0,0,0,6,8},
{0,0,8,5,0,0,0,1,0},
{0,9,0,0,0,0,4,0,0},

我并没有去看他的算法是什么样的,索性就直接自己重新写了个。在对fillNumber()方法的实现过程中对于嵌套调用让我收获颇多,深刻体会到了JAVA的传值问题。
现在把代码贴出与大家共享,请多多指正!


import java.util.ArrayList;
import java.util.List;

public class Sudoku {

int[][] originalSudokuArray = null;
private static int[] oneToNine = {1,2,3,4,5,6,7,8,9};
private List<int[][]> collector = new ArrayList<int[][]>();

public Sudoku(int[][] sudokuArray){
this.originalSudokuArray = sudokuArray;
}

private void solveSudoku(){
fillNumber(originalSudokuArray,0,0);
printSudokuArray();
}

private void fillNumber(int[][] sudokuArray,int rowPosition,int colPosition){
for(int i=rowPosition;i<9;i++){
for(int j=0;j<9;j++){
if(sudokuArray[i][j]==0){
int[][] newSudokuArray = new int[9][9];
for(int number:oneToNine){//
if(numberIsLegal(sudokuArray,number,i,j)){
newSudokuArray = valueDeliver(sudokuArray);
newSudokuArray[i][j] = number;
if(hasNullBox(newSudokuArray)){
fillNumber(newSudokuArray,i,j);
}else{
collector.add(newSudokuArray);
return;
}
}
}
if(newSudokuArray[i][j]==0){
sudokuArray[rowPosition][colPosition] = 0;
}
return;
}
}
}
return;
}

private int[][] valueDeliver(int[][] sudokuArray){
int[][] newArray = new int[sudokuArray.length][sudokuArray[0].length];
for(int i=0,len=sudokuArray.length;i<len;i++){
for(int j=0,len1=sudokuArray[0].length;j<len1;j++){
newArray[i][j] = sudokuArray[i][j];
}
}
return newArray;
}


private boolean numberIsLegal(int[][] sudokuArray,int number,int rowPosition,int colPosition){
boolean legal = true;

//水平
for(int i=0;i<9;i++){
if(sudokuArray[rowPosition][i]==0) continue;
if(sudokuArray[rowPosition][i]==number){
legal = false;
}
}
//垂直
for(int i=0;i<9;i++){
if(sudokuArray[i][colPosition]==0) continue;
if(sudokuArray[i][colPosition]==number){
legal = false;
}
}
//九格
int boxRowStart = (rowPosition/3)*3;
int boxColStart = (colPosition/3)*3;
for(int i=boxRowStart;i<boxRowStart+3;i++){
for(int j=boxColStart;j<boxColStart+3;j++){
if(sudokuArray[i][j]==0) continue;
if(sudokuArray[i][j]==number){
legal = false;
}
}
}
return legal;
}
private boolean hasNullBox(int[][] sudokuArray){
boolean nullFlag = false;
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(sudokuArray[i][j]==0){
nullFlag = true;
}
}
}
return nullFlag;
}

private void printSudokuArray(){
for(int[][] intArray:collector){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
System.out.print(intArray[i][j]+" ");
}
System.out.println();
}
System.out.println("---------------------------------");
}
System.out.println("总共"+collector.size()+"个解!");
}



public static void main(String[] args){
int[][] originalArray = {
{8,0,0,0,0,0,0,0,0},
{0,0,0,6,0,0,0,0,0},
{0,7,0,0,9,0,2,0,0},
{0,5,0,0,0,7,0,0,0},
{0,0,0,0,4,5,7,0,0},
{0,0,0,1,0,0,0,3,0},
{0,0,1,0,0,0,0,6,8},
{0,0,8,5,0,0,0,1,0},
{0,9,0,0,0,0,4,0,0},
};
Sudoku sdk = new Sudoku(originalArray);
sdk.solveSudoku();
}
}

//测试数据:

//4个解
//{0,0,0,0,0,0,0,0,0},
//{0,0,0,0,0,1,0,0,3},
//{0,0,0,9,3,2,6,8,1},
//{6,5,0,2,9,0,7,3,8},
//{7,3,0,8,0,5,4,6,9},
//{9,0,0,0,7,3,5,1,2},
//{2,1,5,3,4,7,8,9,6},
//{4,6,8,1,2,0,0,0,7},
//{3,7,9,5,8,6,1,0,0},

//1个
//{1,0,0,0,6,0,0,0,7},
//{0,9,6,7,0,1,0,4,0},
//{0,4,7,0,3,0,6,8,0},
//{6,5,0,2,0,4,7,0,8},
//{0,0,2,0,0,5,4,6,0},
//{0,8,4,6,0,3,0,0,2},
//{0,1,5,0,4,0,8,9,0},
//{4,0,8,1,0,9,3,0,5},
//{3,7,0,5,0,6,0,2,4},

//1个
//{8,0,0,0,0,0,0,0,0},
//{0,0,3,6,0,0,0,0,0},
//{0,7,0,0,9,0,2,0,0},
//{0,5,0,0,0,7,0,0,0},
//{0,0,0,0,4,5,7,0,0},
//{0,0,0,1,0,0,0,3,0},
//{0,0,1,0,0,0,0,6,8},
//{0,0,8,5,0,0,0,1,0},
//{0,9,0,0,0,0,4,0,0},

//比上面只少了一个数字,1634个解
//{8,0,0,0,0,0,0,0,0},
//{0,0,0,6,0,0,0,0,0},
//{0,7,0,0,9,0,2,0,0},
//{0,5,0,0,0,7,0,0,0},
//{0,0,0,0,4,5,7,0,0},
//{0,0,0,1,0,0,0,3,0},
//{0,0,1,0,0,0,0,6,8},
//{0,0,8,5,0,0,0,1,0},
//{0,9,0,0,0,0,4,0,0},

好的,以下是用 Python 写的一个数独程序,配有注释说明: ```python # 数独的题目,使用0表示空格 grid = [[3, 0, 6, 5, 0, 8, 4, 0, 0], [5, 2, 0, 0, 0, 0, 0, 0, 0], [0, 8, 7, 0, 0, 0, 0, 3, 1], [0, 0, 3, 0, 0, 0, 0, 2, 0], [9, 0, 0, 8, 0, 0, 0, 0, 5], [0, 5, 0, 0, 0, 0, 6, 0, 0], [1, 3, 0, 0, 0, 0, 2, 5, 0], [0, 0, 0, 0, 0, 0, 0, 7, 4], [0, 0, 5, 2, 0, 6, 3, 0, 0]] def solve(grid): """ 数独函数,返回解决方案 """ # 获取一个未填写的位置,如果没有则返回True,表示已解决 find = get_blank(grid) if not find: return True else: row, col = find # 尝试将数字1-9填入这个位置并进行验证 for num in range(1, 10): if is_valid(grid, row, col, num): grid[row][col] = num # 递归调用,继续尝试解决剩下的部分 if solve(grid): return True # 如果上面的解决方案没有返回True,则将当前位置重新赋值为0,进行下一次尝试 grid[row][col] = 0 # 如果尝试了1-9都无法解决,则返回False return False def get_blank(grid): """ 获取一个未填写的位置 """ for row in range(9): for col in range(9): if grid[row][col] == 0: return (row, col) return None def is_valid(grid, row, col, num): """ 验证填写的数字是否合法 """ # 验证行 for i in range(9): if grid[row][i] == num: return False # 验证列 for i in range(9): if grid[i][col] == num: return False # 验证3x3的区域 y = (row // 3) * 3 x = (col // 3) * 3 for i in range(3): for j in range(3): if grid[y+i][x+j] == num: return False # 如果以上验证都通过,表明填写的数字是合法的 return True # 调用数独函数 solve(grid) # 打印解决方案 for i in range(9): for j in range(9): print(grid[i][j], end=" ") print() ``` 希望这个程序对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值