一、 Github项目地址
https://github.com/heyooo-98/-
二、 PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 60 | 20 |
Estimate | 估计这个任务需要多少时间 | 1440 | 1800 |
Development | 开发 | 360 | 240 |
Analysis | 需求分析 (包括学习新技术) | 120 | 100 |
Design Spec | 生成设计文档 | 120 | 120 |
Design Review | 设计复审 | 60 | 60 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 60 | 60 |
Design | 具体设计 | 120 | 180 |
Coding | 具体编码 | 360 | 240 |
Code Review | 代码复审 | 60 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 120 | 100 |
Reporting | 报告 | 120 | 90 |
Test Repor | 测试报告 | 30 | 30 |
Size Measurement | 计算工作量 | 30 | 30 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 60 | 30 |
合计 | 3120 | 3130 |
三、解题思路
刚拿到题目看了一遍没有任何头绪,然后又仔细把题目重复的看了几次,在草稿纸上也写了一遍,设计了解题思路和方法,刚开始写的时候其实翻了不少书,仔细研究了一下算法,作为数学学渣的我只能再把算法重新看了一遍,然后得出最后的使用方法。操作的时候按照步骤一步一步的来,有了框架结构操作起来就很方便了。
四、设计实现过程
1.流程
将的数字保存到num.txt文件中,再把底下附的源代码保存为Sudoku.java。
然后在cmd命令行模型下输入:
1
2
|
javac Sudoku.java java Sudoku <num.tx |
即可得到结果
2.代码实现
部分代码展示
public Sudoku(){} //在对应数独位置插入正确值 public void insert(int row,int col,int value){ correctNum[row][col]=value; availableNum[row][col]=null; delete(row,col,value); } //每插入一个数值,就删除相应的行列和小框框3X3数独里对应的ArrayList里可能的该值 public void delete(int row,int col,int value){ //delte row for(int i=1;i<10;i++){ if (availableNum[row][i]!=null) availableNum[row][i].remove(new Integer(value)); } //delete column for(int i=1;i<10;i++){ if (availableNum[i][col]!=null) availableNum[i][col].remove(new Integer(value)); } //delete box num int[] itsCenter=judgeCenterPos(row,col); for(int temp1=itsCenter[0]-1;temp1<=itsCenter[0]+1;temp1++) for(int temp2=itsCenter[1]-1;temp2<=itsCenter[1]+1;temp2++) if(availableNum[temp1][temp2]!=null){ availableNum[temp1][temp2].remove(new Integer(value)); } }
//暴力破解 public void violentBreak(){ int i=1,j=1; outer: for(;i<10;i++) for(;j<10;j++) if(correctNum[i][j]!=-1) break outer; violentInsert(i,j,correctNum[i][j],correctNum); } public void violentInsert(int row,int col,int value,int[][] arr){ countNum++; int[][] tempMatrix=new int[10][10]; for(int i=1;i<10;i++) for(int j=1;j<10;j++) tempMatrix[i][j]=arr[i][j]; tempMatrix[row][col]=value; //不能insert的话说明填满了 int[] insertPos=canInsert(tempMatrix); if(insertPos[0]==-1){ System.out.println("all insert is done.This is the last Sudoku:"); printSudoku(tempMatrix); return; } for(int val=1;val<=10;val++){ if(val==10){ tempMatrix=null; //让JVM回收垃圾 //System.out.println("value=10 happened."); return; } if(judgeIfViolentInsert(insertPos[0],insertPos[1],val,tempMatrix)){ //System.out.println("insert happened."); violentInsert(insertPos[0],insertPos[1],val,tempMatrix); } } } public int[] canInsert(int[][] tempMatrix){ int[] pos={-1,-1}; for(int i=1;i<10;i++) for(int j=1;j<10;j++){ if(tempMatrix[i][j]==-1){ pos[0]=i; pos[1]=j; return pos; } } return pos; } public boolean judgeIfViolentInsert(int row,int col,int value,int[][] tempMatrix){ for(int j=1;j<10;j++) if(value==tempMatrix[row][j]) return false; for(int i=1;i<10;i++) if(value==tempMatrix[i][col]) return false; int[] itsCenter=judgeCenterPos(row,col); for(int temp1=itsCenter[0]-1;temp1<=itsCenter[0]+1;temp1++) for(int temp2=itsCenter[1]-1;temp2<=itsCenter[1]+1;temp2++) if(value==tempMatrix[temp1][temp2]) return false; return true; }
3.代码逻辑解析:
1、建立一个9X9矩阵保存数独正确的值
2、建立一个9X9列表,每个列表里保存着该位置,数独可以填入的可能值
如ArrayList[1][1]={1,2,3}即1,1这个位置的数独可能可以填入其中一个
当矩阵该位置已保存了正确值时,清空对应位置的ArrayList
3、当列表ArrayList里只有一个可能值时,那个值就是数独的正确值,将该值填入数独矩阵
并更新ArrayList
五、 心路历程与收获
一开始没有注意是要命令行程序,本来以为弄好的我把代码发给同学帮我看一下的时候,他提醒了我,于是我又只好重新写,大部分时间都花在github上传项目上了,当发现自己程序没有按照要求来的时候整个人都不好了,其实可以使用main()方法里面的args[]数组改一下,但是发现了好多问题,只好重新写。用暴力破解法可能是最快的方法了,写的很匆忙,其中还有很多不足之处,希望下次能够吸取教训,继续努力。在短短的半天时间里也能写出个大概,有时候还是要逼自己一把比较好。