1. 程式人生 > >用Java實現N*N的標準數獨及對角線數獨解題

用Java實現N*N的標準數獨及對角線數獨解題

<span style="font-size: x-large;"><strong>1、引言</strong></span>

前一段時間迷上了數獨遊戲(不知道數獨的同學請自行百度,或點這裡瞭解),就有了想程式設計實現解題的想法。一直拖到最近,終於抽空使用Java實現了3*3標準數獨的解題,並在其基礎上抽象出了N*N的標準數獨及對角線數獨的解題。現和眾位分享相關的程式碼和過程。

特別說明:這裡的N*N標準數獨,指的是N=n*n(n為正整數),即4*4、9*9、16*16、25*25……(n=1沒意義)

2、解題思路
數獨的解題方法有很多種,有興趣的同學可以自行百度或
點這裡瞭解


我使用的是最簡單的,也是比較容易實現的基礎摒除法。
在每個空格上,都遞迴嘗試1~N的每個值的可能情況,校驗每個值是否符合基礎摒除法,不符合則嘗試下一個,直至嘗試N個值結束。
引用
基礎摒除法就是利用1~N的值在每一行、每一列、每一個N宮格都只能出現一次的規則進行解題的方法。基礎摒除法可以分為行摒除、列摒除、N宮格摒除。


3、實現過程
3.1 幾個定義
1、N宮格中,“空格”的定義,採用空字串(”“)或0表示;

2、N宮格中,行或列的索引定義,為編碼方便採用0~(N-1)來表示,如:第4行第5列的格子對應的行列索引為:row=3和col=4;

3、N宮格中,填空內容的定義,採用長度為N的一維陣列表示,如:
n=2,即N=4

Java程式碼  收藏程式碼
  1. // 4*4填空內容
  2. String[] dataArray = new String[] {  
  3.     ”1”“2”“3”“4”
  4. });  
// 4*4填空內容
String[] dataArray = new String[] {
    "1", "2", "3", "4"
});


n=3,即N=9

Java程式碼  收藏程式碼
  1. // 9*9填空內容
  2. String[] dataArray = new String[] {  
  3.     ”1”“2”“3”“4”“5”“6”“7”“8”“9”
  4. });  
// 9*9填空內容 
String[] dataArray = new String[] {
"1", "2", "3", "4", "5", "6", "7", "8", "9"
});


n=4,即N=16

Java程式碼  收藏程式碼
  1. // 16*16填空內容
  2. String[] dataArray = new String[] {  
  3.     ”1”“2”“3”“4”“5”“6”“7”“8”“9”“A”“B”“C”“D”“E”“F”“G”
  4. });  
// 16*16填空內容 
String[] dataArray = new String[] {
"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G"
});



當然,N宮格的填空內容,不侷限於1~N的數值,你可以使用任何非“空格”的且互不一樣的字串,如:

Java程式碼  收藏程式碼
  1. // 4*4填空內容
  2. String[] dataArray = new String[] {  
  3.     ”張三”“李四”“王五”“趙六”
  4. });  
// 4*4填空內容 
String[] dataArray = new String[] {
"張三", "李四", "王五", "趙六"
});



4、N宮格中,N*N的數獨題目或填空結果定義,採用長度為N*N的二維陣列表示,如:

Java程式碼  收藏程式碼
  1. // 9*9數獨題目
  2. String[][] resultArray = new String[][] {  
  3.     {  
  4.         ”0”“2”“0”“0”“0”“0”“0”“0”“0”
  5.     }, {  
  6.         ”5”“0”“6”“0”“0”“0”“3”“0”“9”
  7.     }, {  
  8.         ”0”“8”“0”“5”“0”“2”“0”“6”“0”
  9.     }, {  
  10.         ”0”“0”“5”“0”“7”“0”“1”“0”“0”
  11.     }, {  
  12.         ”0”“0”“0”“2”“0”“8”“0”“0”“0”
  13.     }, {  
  14.         ”0”“0”“4”“0”“1”“0”“8”“0”“0”
  15.     }, {  
  16.         ”0”“5”“0”“8”“0”“7”“0”“3”“0”
  17.     }, {  
  18.         ”7”“0”“2”“0”“0”“0”“4”“0”“5”
  19.     }, {  
  20.         ”0”“4”“0”“0”“0”“0”“0”“7”“0”
  21.     }  
  22. };  
// 9*9數獨題目 
String[][] resultArray = new String[][] {
{
"0", "2", "0", "0", "0", "0", "0", "0", "0"
}, {
"5", "0", "6", "0", "0", "0", "3", "0", "9"
}, {
"0", "8", "0", "5", "0", "2", "0", "6", "0"
}, {
"0", "0", "5", "0", "7", "0", "1", "0", "0"
}, {
"0", "0", "0", "2", "0", "8", "0", "0", "0"
}, {
"0", "0", "4", "0", "1", "0", "8", "0", "0"
}, {
"0", "5", "0", "8", "0", "7", "0", "3", "0"
}, {
"7", "0", "2", "0", "0", "0", "4", "0", "5"
}, {
"0", "4", "0", "0", "0", "0", "0", "7", "0"
}
};



5、N宮格中,每個格子的索引定義,採用從0開始的整數來表示,那麼N*N格子索引範圍為:0~(N*N-1),如:9*9的索引範圍為0~80,那麼,格子索引和行列索引可以進行相關的換算;


3.2 基礎摒除法的Java實現

1、行摒除

Java程式碼  收藏程式碼
  1. / 
  2.   行校驗 
  3.   @param resultArray 
  4.   @param row 
  5.   @param value 
  6.   @return 
  7.  /
  8. privatestaticboolean checkRow(final String[][] resultArray, int row, String value) {  
  9.     int arrayLen = resultArray.length;  
  10.     for (int i = 0; i < arrayLen; i++) {  
  11.         if (value.equals(resultArray[row][i])) {  
  12.             returnfalse;  
  13.         }  
  14.     }  
  15.     returntrue;  
  16. }  
/ 
* 行校驗
* @param resultArray
* @param row
* @param value
* @return
*/
private static boolean checkRow(final String[][] resultArray, int row, String value) {
int arrayLen = resultArray.length;
for (int i = 0; i < arrayLen; i++) {
if (value.equals(resultArray[row][i])) {
return false;
}
}
return true;
}



2、列摒除

Java程式碼  收藏程式碼
  1. / 
  2.   列校驗 
  3.   @param resultArray 
  4.   @param col 
  5.   @param value 
  6.   @return 
  7.  /
  8. privatestaticboolean checkColumn(final String[][] resultArray, int col, String value) {  
  9.     int arrayLen = resultArray.length;  
  10.     for (int i = 0; i < arrayLen; i++) {  
  11.         if (value.equals(resultArray[i][col])) {  
  12.             returnfalse;  
  13.         }  
  14.     }  
  15.     returntrue;  
  16. }  
/ 
* 列校驗
* @param resultArray
* @param col
* @param value
* @return
*/
private static boolean checkColumn(final String[][] resultArray, int col, String value) {
int arrayLen = resultArray.length;
for (int i = 0; i < arrayLen; i++) {
if (value.equals(resultArray[i][col])) {
return false;
}
}
return true;
}



3、N宮摒除

這裡實現比較難的一點在於,根據給定行、列計算其所在宮的行列開始值

Java程式碼  收藏程式碼
  1. / 
  2.   宮校驗 
  3.   @param resultArray 
  4.   @param row 
  5.   @param col 
  6.   @param value 
  7.   @return 
  8.  /
  9. privatestaticboolean checkBlock(final String[][] resultArray, int row, int col, String value) {  
  10.     int arrayLen = resultArray.length;  
  11.     int blockLen = (int) Math.sqrt(arrayLen);  
  12.     int blockRowIndex = (int) row / blockLen;  
  13.     int blockColIndex = (int) col / blockLen;  
  14.     int blockRowStart = blockLen  blockRowIndex;  
  15.     int blockColStart = blockLen * blockColIndex;  
  16.     for (int i = 0; i < blockLen; i++) {  
  17.         int rowIndex = blockRowStart + i;  
  18.         for (int j = 0; j < blockLen; j++) {  
  19.             int colIndex = blockColStart + j;  
  20.             if (value.equals(resultArray[rowIndex][colIndex])) {  
  21.                 returnfalse;  
  22.             }  
  23.         }  
  24.     }  
  25.     returntrue;  
  26. }  
/ 
* 宮校驗
* @param resultArray
* @param row
* @param col
* @param value
* @return
*/
private static boolean checkBlock(final String[][] resultArray, int row, int col, String value) {
int arrayLen = resultArray.length;
int blockLen = (int) Math.sqrt(arrayLen);
int blockRowIndex = (int) row / blockLen;
int blockColIndex = (int) col / blockLen;
int blockRowStart = blockLen * blockRowIndex;
int blockColStart = blockLen * blockColIndex;
for (int i = 0; i &lt; blockLen; i++) {
    int rowIndex = blockRowStart + i;
    for (int j = 0; j &lt; blockLen; j++) {
        int colIndex = blockColStart + j;
        if (value.equals(resultArray[rowIndex][colIndex])) {
            return false;
        }
    }
}
return true;
}



4、對角線摒除(左上至右下)

Java程式碼  收藏程式碼
  1. / 
  2.   對角線校驗(左上至右下) 
  3.   @param resultArray 
  4.   @param value 
  5.   @return 
  6.  */
  7. privatestaticboolean checkLeftTop2RightBottom(final String[][] resultArray, int row, int col, String value) {  
  8.     if (row == col) {  
  9.         int arrayLen = resultArray.length;  
  10.         for (int i = 0; i < arrayLen; i++) {  
  11.             if (value.equals(resultArray[i][i])) {  
  12.                 returnfalse;  
  13.             }  
  14.         }  
  15.     }  
  16.     returntrue;  
  17. }  
/ 
* 對角線校驗(左上至右下)
* @param resultArray
* @param value
* @return
*/
private static boolean checkLeftTop2RightBottom(final String[][] resultArray, int row, int col, String value) {
if (row == col) {
int arrayLen = resultArray.length;
for (int i = 0; i < arrayLen; i++) {
if (value.equals(resultArray[i][i])) {
return false;
}
}
}
return true;
}



5、對角線摒除(左下至右上)

Java程式碼  收藏程式碼
  1. / 
  2.   對角線校驗(左下至右上) 
  3.   @param resultArray 
  4.   @param value 
  5.   @return 
  6.  */
  7. privatestaticboolean checkLeftBottom2RightTop(final String[][] resultArray, int row, int col, String value) {  
  8.     int arrayLen = resultArray.length;  
  9.     if ((row + col) == (arrayLen - 1)) {  
  10.         for (int i = 0; i < arrayLen; i++) {  
  11.             if (value.equals(resultArray[arrayLen - i - 1][i])) {  
  12.                 returnfalse;  
  13.             }  
  14.         }  
  15.     }  
  16.     returntrue;  
  17. }  
/ 
* 對角線校驗(左下至右上)
* @param resultArray
* @param value
* @return
*/
private static boolean checkLeftBottom2RightTop(final String[][] resultArray, int row, int col, String value) {
int arrayLen = resultArray.length;
if ((row + col) == (arrayLen - 1)) {
for (int i = 0; i < arrayLen; i++) {
if (value.equals(resultArray[arrayLen - i - 1][i])) {
return false;
}
}
}
return true;
}



6、基礎摒除法

Java程式碼  收藏程式碼
  1. / 
  2.   執行所有校驗 
  3.   @param resultArray 
  4.   @param row 
  5.   @param col 
  6.   @param value 
  7.   @param checkCross 
  8.   @return 
  9.  /
  10. privatestaticboolean checkAll(final String[][] resultArray, int row, int col, String value, boolean checkCross) {  
  11.     // 行校驗
  12.     if (!checkRow(resultArray, row, value)) {  
  13.         returnfalse;  
  14.     }  
  15.     // 列校驗
  16.     if (!checkColumn(resultArray, col, value)) {  
  17.         returnfalse;  
  18.     }  
  19.     // 宮校驗
  20.     if (!checkBlock(resultArray, row, col, value)) {  
  21.         returnfalse;  
  22.     }  
  23.     // 對角線校驗
  24.     if (checkCross) {  
  25.         // 對角線校驗(左上至右下)
  26.         if (!checkLeftTop2RightBottom(resultArray, row, col, value)) {  
  27.             returnfalse;  
  28.         }  
  29.         // 對角線校驗(左下至右上)
  30.         if (!checkLeftBottom2RightTop(resultArray, row, col, value)) {  
  31.             returnfalse;  
  32.         }  
  33.     }  
  34.     returntrue;  
  35. }  
/ 
* 執行所有校驗
* @param resultArray
* @param row
* @param col
* @param value
* @param checkCross
* @return
*/
private static boolean checkAll(final String[][] resultArray, int row, int col, String value, boolean checkCross) {
// 行校驗
if (!checkRow(resultArray, row, value)) {
return false;
}
// 列校驗
if (!checkColumn(resultArray, col, value)) {
    return false;
}

// 宮校驗
if (!checkBlock(resultArray, row, col, value)) {
    return false;
}

// 對角線校驗
if (checkCross) {
    // 對角線校驗(左上至右下)
    if (!checkLeftTop2RightBottom(resultArray, row, col, value)) {
        return false;
    }
    // 對角線校驗(左下至右上)
    if (!checkLeftBottom2RightTop(resultArray, row, col, value)) {
        return false;
    }
}

return true;
}



3.3 解題實現

解題採用遞迴的方式進行,直至解題完成並打印出結果,相關實現程式碼如下

1、校驗是否已填好的實現如下:

Java程式碼  收藏程式碼
  1. / 
  2.   校驗是否已經填好 
  3.   @param value 
  4.   @return 
  5.  /
  6. privatestaticboolean isUnselect(String value) {  
  7.     return“”.equals(value) || “0”.equals(value);  
  8. }  
/ 
* 校驗是否已經填好
* @param value
* @return
*/
private static boolean isUnselect(String value) {
return "".equals(value) || "0".equals(value);
}



2、遞迴過程的填空結果傳遞,需要複製二維陣列,其實現如下:

Java程式碼  收藏程式碼
  1. / 
  2.   複製陣列 
  3.   @param array 
  4.   @return 
  5.  /
  6. privatestatic String[][] copyArray(final String[][] array) {  
  7.     int rowCount = array.length;  
  8.     int colCount = array[0].length;  
  9.     String[][] copy = new String[rowCount][colCount];  
  10.     for (int i = 0; i < rowCount; i++) {  
  11.         for (int j = 0; j < colCount; j++) {  
  12.             copy[i][j] = array[i][j];  
  13.         }  
  14.     }  
  15.     return copy;  
  16. }  
/ 
* 複製陣列
* @param array
* @return
*/
private static String[][] copyArray(final String[][] array) {
int rowCount = array.length;
int colCount = array[0].length;
String[][] copy = new String[rowCount][colCount];
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < colCount; j++) {
copy[i][j] = array[i][j];
}
}
return copy;
}



3、列印解題結果的實現程式碼如下:

Java程式碼  收藏程式碼
  1. / 
  2.   輸出結果 
  3.   @param resultArray 
  4.  */
  5. privatestaticvoid printResult(final String[][] resultArray) {  
  6.     System.out.println(”\n——————————–”);  
  7.     int arrayLen = resultArray.length;  
  8.     for (int i = 0; i < arrayLen; i++) {  
  9.         System.out.println(Arrays.asList(resultArray[i]));  
  10.     }  
  11. }  
/ 
* 輸出結果
* @param resultArray
*/
private static void printResult(final String[][] resultArray) {
System.out.println("\n--------------------------------");
int arrayLen = resultArray.length;
for (int i = 0; i < arrayLen; i++) {
System.out.println(Arrays.asList(resultArray[i]));
}
}



4、遞迴解題演算法(核心)

Java程式碼  收藏程式碼
  1. / 
  2.   數獨解題 
  3.   @param dataArray 待選列表 
  4.   @param resultArray 前面(resultIndex-1)個的填空結果 
  5.   @param resultIndex 選擇索引,從0開始 
  6.   @param checkCross 是否是對角線數獨 
  7.  /
  8. privatestaticvoid sudoSelect(String[] dataArray, final String[][] resultArray, int resultIndex, boolean checkCross) {  
  9.     int resultLen = resultArray.length;  
  10.     if (resultIndex >= (int) Math.pow(resultLen, 2)) {  
  11.         // 全部填完時,輸出排列結果
  12.         printResult(resultArray);  
  13.         return;  
  14.     }  
  15.     int row = (int) resultIndex / resultLen;  
  16.     int col = resultIndex % resultLen;  
  17.     if (isUnselect(resultArray[row][col])) {  
  18.         // 逐個嘗試,遞迴選擇下一個
  19.         for (int i = 0; i < dataArray.length; i++) {  
  20.             if (checkAll(resultArray, row, col, dataArray[i], checkCross)) {  
  21.                 // 排列結果不存在該項,才可選擇
  22.                 String[][] resultCopy = copyArray(resultArray);  
  23.                 resultCopy[row][col] = dataArray[i];  
  24.                 sudoSelect(dataArray, resultCopy, resultIndex + 1, checkCross);  
  25.             }  
  26.         }  
  27.     } else {  
  28.         // 遞迴選擇下一個
  29.         String[][] resultCopy = copyArray(resultArray);  
  30.         sudoSelect(dataArray, resultCopy, resultIndex + 1, checkCross);  
  31.     }  
  32. }  
/ 
* 數獨解題
* @param dataArray 待選列表
* @param resultArray 前面(resultIndex-1)個的填空結果
* @param resultIndex 選擇索引,從0開始
* @param checkCross 是否是對角線數獨
*/
private static void sudoSelect(String[] dataArray, final String[][] resultArray, int resultIndex, boolean checkCross) {
int resultLen = resultArray.length;
if (resultIndex >= (int) Math.pow(resultLen, 2)) {
// 全部填完時,輸出排列結果
printResult(resultArray);
return;
}
int row = (int) resultIndex / resultLen;
int col = resultIndex % resultLen;
if (isUnselect(resultArray[row][col])) {
    // 逐個嘗試,遞迴選擇下一個
    for (int i = 0; i &lt; dataArray.length; i++) {
        if (checkAll(resultArray, row, col, dataArray[i], checkCross)) {
            // 排列結果不存在該項,才可選擇
            String[][] resultCopy = copyArray(resultArray);

            resultCopy[row][col] = dataArray[i];
            sudoSelect(dataArray, resultCopy, resultIndex + 1, checkCross);
        }
    }
} else {
    // 遞迴選擇下一個
    String[][] resultCopy = copyArray(resultArray);
    sudoSelect(dataArray, resultCopy, resultIndex + 1, checkCross);
}
}



3.4 其它

1、根據待選陣列,初始化生成二維結果陣列;

Java程式碼  收藏程式碼
  1. / 
  2.   初始化結果陣列 
  3.   @param dataArray 待選列表 
  4.   @return 
  5.  /
  6. publicstatic String[][] initResultArray(String[] dataArray) {  
  7.     int arrayLen = dataArray.length;  
  8.     String[][] resultArray = new String[arrayLen][arrayLen];  
  9.     for (int i = 0; i < arrayLen; i++) {  
  10.         for (int j = 0; j < arrayLen; j++) {  
  11.             resultArray[i][j] = ”0”;  
  12.         }  
  13.     }  
  14.     return resultArray;  
  15. }  
/ 
* 初始化結果陣列
* @param dataArray 待選列表
* @return
*/
public static String[][] initResultArray(String[] dataArray) {
int arrayLen = dataArray.length;
String[][] resultArray = new String[arrayLen][arrayLen];
for (int i = 0; i < arrayLen; i++) {
for (int j = 0; j < arrayLen; j++) {
resultArray[i][j] = "0";
}
}
return resultArray;
}



2、根據N*N長度的字串,初始化生成二維結果陣列;

Java程式碼  收藏程式碼
  1. / 
  2.   初始化結果陣列 
  3.   @param resultString 結果字串 
  4.   @return 
  5.  /
  6. publicstatic String[][] initResultArray(String resultString) {  
  7.     int arrayLen = (int) Math.sqrt(resultString.length());  
  8.     String[][] resultArray = new String[arrayLen][arrayLen];  
  9.     for (int i = 0; i < arrayLen; i++) {  
  10.         for (int j = 0; j < arrayLen; j++) {  
  11.             resultArray[i][j] = ”“ + resultString.charAt(i * arrayLen + j);  
  12.         }  
  13.     }  
  14.     return resultArray;  
  15. }  
/ 
* 初始化結果陣列
* @param resultString 結果字串
* @return
*/
public static String[][] initResultArray(String resultString) {
int arrayLen = (int) Math.sqrt(resultString.length());
String[][] resultArray = new String[arrayLen][arrayLen];
for (int i = 0; i < arrayLen; i++) {
for (int j = 0; j < arrayLen; j++) {
resultArray[i][j] = "" + resultString.charAt(i * arrayLen + j);
}
}
return resultArray;
}



4、測試

4.1 測試程式碼

1、為測試方便,進行了幾個封裝

Java程式碼  收藏程式碼
  1. / 
  2.   9*9數獨給定已選字串求解 
  3.   @param resultString 數獨題目 
  4.  /
  5. publicstaticvoid sudoSelect(String resultString) {  
  6.     String[][] resultArray = initResultArray(resultString);  
  7.     sudoSelect(new String[] {  
  8.             ”1”“2”“3”“4”“5”“6”“7”“8”“9”
  9.     }, resultArray);  
  10. }  
  11. / 
  12.   N*N數獨給定結果陣列求解 
  13.   @param dataArray 待選列表 
  14.   @param resultArray 已選結果陣列 
  15.  /
  16. publicstaticvoid sudoSelect(String[] dataArray, final String[][] resultArray) {  
  17.     sudoSelect(dataArray, resultArray, false);  
  18. }  
  19. / 
  20.   排列選擇(從列表中選擇n個排列) 
  21.   @param dataArray 待選列表 
  22.   @param resultArray 已選結果 
  23.   @param checkCross 是否校驗對角線 
  24.  /
  25. publicstaticvoid sudoSelect(String[] dataArray, final String[][] resultArray, boolean checkCross) {  
  26.     sudoSelect(dataArray, resultArray, 0, checkCross);  
  27. }  
/ 
* 9*9數獨給定已選字串求解
* @param resultString 數獨題目
*/
public static void sudoSelect(String resultString) {
String[][] resultArray = initResultArray(resultString);
sudoSelect(new String[] {
“1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9”
}, resultArray);
}

/**
* N*N數獨給定結果陣列求解
* @param dataArray 待選列表
* @param resultArray 已選結果陣列
*/
public static void sudoSelect(String[] dataArray, final String[][] resultArray) {
sudoSelect(dataArray, resultArray, false);
}

/**
* 排列選擇(從列表中選擇n個排列)
* @param dataArray 待選列表
* @param resultArray 已選結果
* @param checkCross 是否校驗對角線
*/
public static void sudoSelect(String[] dataArray, final String[][] resultArray, boolean checkCross) {
sudoSelect(dataArray, resultArray, 0, checkCross);
}



2、測試入口

Java程式碼  收藏程式碼
  1. publicstaticvoid main(String[] args) {  
  2.     // 求解給定數獨所有可能
  3.     sudoSelect(new String[] {  
  4.             ”1”“2”“3”“4”“5”“6”“7”“8”“9”
  5.     }, new String[][] {  
  6.             {  
  7.                     ”9”“1”“2”“0”“0”“7”“0”“5”“0”
  8.             }, {  
  9.                     ”0”“0”“3”“0”“5”“9”“0”“2”“1”
  10.             }, {  
  11.                     ”0”“0”“5”“4”“1”“2”“0”“0”“9”
  12.             }, {  
  13.                     ”0”“8”“0”“0”“4”“5”“9”“0”“2”
  14.             }, {  
  15.                     ”0”“0”“0”“0”“7”“0”“5”“0”“0”
  16.             }, {  
  17.                     ”5”“0”“4”“0”“6”“0”“0”“1”“0”
  18.             }, {  
  19.                     ”0”“0”“0”“5”“0”“6”“0”“0”“0”
  20.             }, {  
  21.                     ”2”“5”“0”“7”“0”“0”“8”“0”“0”
  22.             }, {  
  23.                     ”0”“3”“0”“0”“0”“0”“0”“9”“5”
  24.             }  
  25.     });  
  26.     // 求解給定數獨所有可能
  27.     // #9806 002300609000000075100060000504100008060050040800007102000030001250000000907004200
  28.     // #9807 010000000000294000008300709180002040050000080030800096401003800000471000000000020
  29.     // #9808 100200905000080000400600023010005060000060000050400030840001007000070000507002001
  30.     // #9809 300500090400000500002310000053080010000090000060050370000021800001000004080007006
  31.     // #9810 010500000090073000804020000400000100780060029002000005000030207000480060000006090
  32.     sudoSelect(”002300609000000075100060000504100008060050040800007102000030001250000000907004200”);  
  33.     sudoSelect(”010000000000294000008300709180002040050000080030800096401003800000471000000000020”);  
  34.     sudoSelect(”100200905000080000400600023010005060000060000050400030840001007000070000507002001”);  
  35.     sudoSelect(”300500090400000500002310000053080010000090000060050370000021800001000004080007006”);  
  36.     sudoSelect(”010500000090073000804020000400000100780060029002000005000030207000480060000006090”);  
  37. }  
public static void main(String[] args) { 
// 求解給定數獨所有可能
sudoSelect(new String[] {
“1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9”
}, new String[][] {
{
“9”, “1”, “2”, “0”, “0”, “7”, “0”, “5”, “0”
}, {
“0”, “0”, “3”, “0”, “5”, “9”, “0”, “2”, “1”
}, {
“0”, “0”, “5”, “4”, “1”, “2”, “0”, “0”, “9”
}, {
“0”, “8”, “0”, “0”, “4”, “5”, “9”, “0”, “2”
}, {
“0”, “0”, “0”, “0”, “7”, “0”, “5”, “0”, “0”
}, {
“5”, “0”, “4”, “0”, “6”, “0”, “0”, “1”, “0”
}, {
“0”, “0”, “0”, “5”, “0”, “6”, “0”, “0”, “0”
}, {
“2”, “5”, “0”, “7”, “0”, “0”, “8”, “0”, “0”
}, {
“0”, “3”, “0”, “0”, “0”, “0”, “0”, “9”, “5”
}
});
// 求解給定數獨所有可能
// http://tieba.baidu.com/p/4813549830
// #9806 002300609000000075100060000504100008060050040800007102000030001250000000907004200
// #9807 01000000000029400000830