生活随笔
收集整理的這篇文章主要介紹了
java数独解法
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
玩了好久的數(shù)獨,前幾天突發(fā)奇想寫一個解法,看了好多文章和源碼,像回溯法和唯一解法,都不太理解其思路,于是就自己動手寫了一個,效率還算可以,有優(yōu)化的空間,但是懶得優(yōu)化了。
整體的解法思路就是列出每個空格的備選數(shù),然后逐一嘗試,可謂是最笨的解法了,分享給大家圖個樂,還希望大佬看到了可以指點一下里面的不足之處。同樣因為懶,就沒做成web應(yīng)用,一個main方法自己跑著玩了就。
代碼里面包含了1-5級的數(shù)獨謎題例子(測試用的,就沒刪除),還有一個從控制臺獲取謎底的方法。
第一次發(fā)文章有些緊張啊,轉(zhuǎn)載的話表明一下出處就行了,廢話不多說,上代碼
import java
.util
.*
;public class ShuDuKey {static boolean done
= false;public static void main(String
[] args
) throws Exception
{Integer
[][] maps1
= {{0,0,0,0,0,0,0,0,3},{8,9,7,6,3,4,5,2,1},{5,4,0,1,9,0,0,0,0},{4,0,0,0,1,5,0,7,0},{0,0,0,8,0,6,0,0,0},{0,1,0,3,4,0,0,0,2},{0,0,0,0,2,3,0,6,4},{0,3,5,0,0,7,2,1,8},{6,0,0,0,0,0,0,0,0}};Integer
[][] maps2
= {{0,1,0,0,0,6,2,0,0},{0,0,0,5,3,0,9,0,8},{6,9,0,2,4,0,0,0,0},{7,0,0,0,0,0,3,9,0},{0,3,5,0,6,0,8,4,0},{0,8,4,0,0,0,0,0,7},{0,0,0,0,5,4,0,3,1},{4,0,6,0,8,3,0,0,0},{0,0,1,9,0,0,0,0,0}};Integer
[][] maps3
= {{4,6,8,0,5,0,0,7,0},{5,0,0,9,7,0,0,0,3},{0,0,0,0,0,1,0,0,8},{0,0,7,0,0,0,0,5,0},{0,9,0,0,2,0,0,4,0},{0,5,0,0,0,0,8,0,0},{6,0,0,2,0,0,0,0,0},{2,0,0,0,6,5,0,0,4},{9,7,0,0,0,0,2,8,6}};Integer
[][] maps4
= {{6,4,0,0,3,8,7,0,9},{5,0,8,9,0,0,0,0,0},{0,0,0,0,1,0,0,0,0},{0,3,0,0,0,0,5,0,0},{0,0,0,7,2,1,0,0,0},{0,0,9,0,0,0,0,7,0},{0,0,0,0,9,0,0,0,0},{0,0,0,0,0,6,4,0,3},{3,0,1,4,7,0,0,8,5}};Integer
[][] maps5
= {{0,0,4,2,0,0,8,0,0},{0,0,0,0,0,0,0,0,0},{0,9,0,0,0,7,0,3,0},{0,0,5,6,8,0,7,0,0},{0,3,0,0,1,0,0,9,0},{0,0,7,0,5,9,1,0,0},{0,2,0,8,0,0,0,7,0},{0,0,0,0,0,0,0,0,0},{0,0,8,0,0,4,2,0,0}};Integer
[][] mapsMax
= {{0,0,5,3,0,0,0,0,0},{8,0,0,0,0,0,0,2,0},{0,7,0,0,1,0,5,0,0},{4,0,0,0,0,5,3,0,0},{0,1,0,0,7,0,0,0,6},{0,0,3,2,0,0,0,8,0},{0,6,0,5,0,0,0,0,9},{0,0,4,0,0,0,0,3,0},{0,0,0,0,0,9,7,0,0}};Integer
[][] sMap
= scanMap();doShuDu(sMap
);}private static Integer
[][] scanMap() {Scanner sc
= new Scanner(System
.in
);System
.out
.println("請輸入數(shù)獨謎題,數(shù)字以空格隔開,空白處數(shù)字以0代替");Integer
[][] result
= new Integer[9][9];for (int i
= 0; i
< result
.length
; i
++) {System
.out
.println("請輸入第"+(i
+1)+"行的數(shù)字:");String
[] strArr
;while (true) {String str
= sc
.nextLine();if("exit".equals(str
)){System
.exit(0);}strArr
= str
.split("\\s+|,|,");if(strArr
.length
!= 9){System
.out
.println("輸入錯誤,請重新輸入"+(i
+1)+"行數(shù)字!");continue;}break;}for (int j
= 0; j
< result
[i
].length
; j
++) {result
[i
][j
] = Integer
.parseInt(strArr
[j
]);}}System
.out
.println("謎題輸入完畢,正在解析中。。。");return result
;}public static void doShuDu(Integer
[][] maps
){long start
= System
.currentTimeMillis();List
<String>[][] first
= doShuDu1(maps
);if(done
){printMap(first
);System
.out
.println("共用時:"+(System
.currentTimeMillis()-start
));return;}System
.out
.println("執(zhí)行第二步————————————————————————————————————————》》》");List
<String>[][] second
= doShuDu2(maps
,first
);if(done
){printMap(second
);System
.out
.println("共用時:"+(System
.currentTimeMillis()-start
));return;}System
.out
.println("執(zhí)行第三步————————————————————————————————————————》》》");}private static List
<String>[][] doShuDu1(Integer
[][] maps
){List
<String>[][] result
= new List[9][9];boolean flag
= true;while(flag
){done
= true;flag
= false;for (int i
= 0; i
< maps
.length
; i
++) {for (int j
= 0; j
< maps
[i
].length
; j
++) {if(maps
[i
][j
] == 0){result
[i
][j
] = getNumList(i
,j
,maps
);if(result
[i
][j
] == null
){return null
;}if(result
[i
][j
].size() == 1){maps
[i
][j
] = Integer
.parseInt(result
[i
][j
].get(0));flag
= true;}done
= false;}else{if(result
[i
][j
] == null
){result
[i
][j
] = new ArrayList<>();result
[i
][j
].add(maps
[i
][j
].toString());}}}}}return result
;}private static List
<String>[][] doShuDu2(Integer
[][] maps
, List
<String>[][] first
) {Map
<String
,List
<String>[][]> resultMap
= new HashMap<>();Integer
[][] tempMaps
= arrayCopy(maps
);List
<String>[][] result
= new List[first
.length
][];for (int i
= 0; i
< first
.length
; i
++) {result
[i
] = first
[i
].clone();}int[][] count
= new int[9][9];boolean flag
= true;while(flag
){flag
= false;i
:for (int i
= 0; i
< first
.length
; i
++) {for (int j
= 0; j
< first
[i
].length
; j
++) {if(result
[i
][j
].size() > 1){boolean re
= true;while(re
){re
= false;if(count
[i
][j
] < result
[i
][j
].size()){tempMaps
[i
][j
] = Integer
.parseInt(result
[i
][j
].get(count
[i
][j
]++));Integer
[][] iarr
= arrayCopy(tempMaps
);List
<String>[][] ls
= doShuDu1(iarr
);if(ls
!= null
) {resultMap
.put(i
+","+j
,result
);result
= ls
;}else{re
= true;}}else {count
[i
][j
] = 0;for (int k
= 0; k
< count
.length
; k
++) {for (int l
= 0; l
< count
[k
].length
; l
++) {if(count
[k
][l
] > 0){i
= k
;j
= l
;}}}result
= resultMap
.get(i
+","+j
);for (int k
= i
; k
< 9; k
++) {for (int l
= 0; l
< 9; l
++) {if(k
== i
&& l
== 0){l
= j
;}tempMaps
[k
][l
] = maps
[k
][l
];}}j
--;break;}}flag
= true;}else{tempMaps
[i
][j
] = Integer
.parseInt(result
[i
][j
].get(0));}}}}return result
;}private static List
<String> getNumList(int i
, int j
, Integer
[][] maps
) {List
<String> temp
= getList();for (int jj
= 0; jj
< maps
[i
].length
; jj
++) {temp
.remove(maps
[i
][jj
]+"");}for (int ii
= 0; ii
< maps
.length
; ii
++) {temp
.remove(maps
[ii
][j
]+"");}int d
= i
/3*3;int h
= j
/3*3;for (int k
= d
; k
< d
+3; k
++) {for (int l
= h
; l
< h
+3; l
++) {temp
.remove(maps
[k
][l
]+"");}}if(temp
.size() > 0){return temp
;}return null
;}private static List
<String> getList(){List
<String> result
= new ArrayList<>();for (int i
= 1; i
< 10; i
++) {result
.add(i
+"");}return result
;}private static Integer
[][] arrayCopy(Integer
[][] oo
){Integer
[][] result
= new Integer[oo
.length
][];for (int i
= 0; i
< oo
.length
; i
++) {result
[i
] = oo
[i
].clone();}return result
;}public static void printMap(Object
[][] map
){for (int i
= 0; i
< 9; i
++) {if(i
%3==0 && i
!=0){System
.out
.println("---------------------");}for (int j
= 0; j
< 9; j
++) {if (j
==8) {System
.out
.println(map
[i
][j
]);} else if(j
== 2 || j
== 5) {System
.out
.print(map
[i
][j
]+" | ");}else{System
.out
.print(map
[i
][j
]+" ");}}}}}
總結(jié)
以上是生活随笔為你收集整理的java数独解法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。