Java数独求解

该博客分享GitHub上的shudu项目,其功能包括自行设计数独输入输出格式、自动求解数独问题并保存结果。介绍了数独解题类的五个函数,重点讲解function函数逻辑,按原理可列举数独所有解法。

#第一次分享项目#
GitHub项目:shudu
功能:
(1)自行设计数独问题的输入和输出数据格式,例如,可以用txt形式存储数独题目。
(2)能够自动求解数独问题。
(3)输出求解结果,保存在文件中。

完整代码:

8package shudu;
910import java.io.File;
11import java.io.FileInputStream;
1213import java.io.FileOutputStream;
14import java.io.IOException;
15import java.io.InputStream;
16import java.io.OutputStream;
1718import java.util.Arrays;
19import java.util.HashMap;
20import java.util.Map;
2122public class demo {
23public static int[][] x= new int[9][9];
2425public static void readFile() {	//读取文件
26、			File fp=new File("D:\\eclipse\\demo\\shudu\\src\\includ.txt");
27、			InputStream i=null;
28try {
29、				i=new FileInputStream(fp);
30//fp可能为空
31int temp;
32int j=0,k=0;//定义一个赋值时候使用的下标
33while((temp=i.read())!=-1) {
34if((char) temp>='0'&&(char) temp<='9') {
35int num = Integer.valueOf(""+(char) temp);
36、						x[j][k]=num;
37、						k++;
38if(k==9) {
39、							k=0;
40、							j++;
41}
42}
43}
44}catch(Exception e) {	
45、				e.printStackTrace();
46}
47finally {
48try {
49、					i.close();
50//可能i并没有指向,简单说就是有没开启的可能
51} catch (IOException e) {
52、					e.printStackTrace();
53}
54}
55}
5657public static final int N=3;
58public static void main(String[] args) {
5960readFile();
61、	    	System.out.println("文件读取结果:");	
62for (int i = 0; i < x.length; i++) {		//输出文件信息
63for (int j = 0; j < x.length; j++) {
64、	                System.out.print(x[i][j]+" ");
65}
66、	            System.out.println();
67}
68、	    	System.out.println("数独解题结果:");
69function(x,0,0);
7071}
7273private static void function(int[][] x, int r, int c) {		//填写x数组的(r,c)坐标以后的所有数字
74if (r>=x.length) {		//填的行号超过了最大值就打印整个数组
75show(x);
76return;
77}
78if (c==0&&(r==x.length/N||r==x.length/N*2||r==x.length)) {		//填写第3、6、9行开头数字的时候要检查一下上边的三行的方块里是不是有重复的数字
79if (!checkedbox(x,r)) {
80return;
81};
8283}
84if (c>=x.length) {		//填写到最后一个元素的时候,要转到下一行开头去
85function(x, r+1, 0);
86return;
87}
8889if (x[r][c]==0) {		//当前的坐标是0的时候才开始循环填写,否则跳过去填写下一个数字
90for (int i = 1; i <= x.length; i++) {
91if (checked(x,r,c,i)) {
92、	                    x[r][c]=i;
93function(x, r, c+1);
94、	                    x[r][c]=0;
95}
96}
97}else{
98function(x, r, c+1);
99}
100}
101private static boolean checkedbox(int[][] x, int r) {
102for (int k = 0; k < x.length; k+=x.length/N) {
103、	            Map<Integer, Integer> map=new HashMap<>();
104for (int i = r-N; i < r; i++) {
105for (int j = k; j < k+x.length/N; j++) {
106if (map.containsKey(x[i][j])) {
107return false;
108}
109、	                    map.put(x[i][j], 1);
110}
111}
112}
113return true;
114}
115116private static boolean checked(int[][] x, int r, int c, int i) {
117for (int j = 0; j < x.length; j++) {
118if (x[j][c]==i) {
119return false;
120}
121if (x[r][j]==i) {
122return false;
123}
124}
125return true;
126}
127128private static void show(int[][] x) {		//将结果输出至控制栏
129for (int i = 0; i < x.length; i++) {
130for (int j = 0; j < x.length; j++) {
131、	                System.out.print(x[i][j]+" ");
132}
133、	            System.out.println();
134}
135、	        System.out.println();               
136、	      File file = new File("./shudu.txt");		//建立输出文件
137、	        OutputStream out = null;
138try {
139、	        	out = new FileOutputStream(file);
140、	        	String str = new String();			//将结果变量强制转换成为可以输出到文件的形式
141for(int i=0;i<x.length;i++) {
142、	        		str = str+Arrays.toString(x[i])+"\n";
143}
144byte[] b = str.getBytes();
145、	        	out.write(b, 0, b.length);
146、	        	out.flush();
147}catch(Exception e) {
148、	        	e.printStackTrace();
149}finally {
150try {
151、					out.close();
152、					System.out.println("结果已保存至文件。");
153}catch (Exception e) {
154// TODO: handle exception
155}
156}
157}
158}

运行结果:
在这里插入图片描述
先将数独问题导入,查找到后导入进程序内,进入解题程序
数独解题类里有五个函数,一是主函数;二是递归的主体函数function,是解决数独的关键,体现循环+递归+回溯的主要逻辑;三和四都是一个辨识函数,一些较为复杂的判断逻辑写成辨识函数可以增加代码的可读性;五是一个打印函数。
function函数的实际意义是填写x[r][c]的数字,更确切的说是填写x数组的(r,c)坐标以后的所有数字,内部基本的结构是4个并列的if,第一个if是填写的行号超过了最大值就打印整个数组;第二个if是填写第3、6、9行开头数字的时候要检查一下上边的三行的方块里是不是有重复的数字;第三个if是填写到最后一个元素的时候,要转到下一行开头去;第四个if是当前的坐标是0的时候才开始循环填写,否则跳过去填写下一个数字。
最后使用checked函数和show函数
按照原理这个方法可以把一个数独的所有解法全部列举出来

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值