GitHub项目地址
PSP表格
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 20 | 20 |
Estimate | 估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | 1260 | 1360 |
Analysis | 需求分析 (包括学习新技术) | 480 | 540 |
Design Spec | 生成设计文档 | 30 | 10 |
Design Review | 设计复审 | 30 | 20 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 10 |
Design | 具体设计 | 30 | 90 |
Coding | 具体编码 | 540 | 600 |
Code Review | 代码复审 | 60 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 60 | 60 |
Reporting | 报告 | 60 | 120 |
Test Repor | 测试报告 | 30 | 60 |
Size Measurement | 计算工作量 | 30 | 60 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 120 | 90 |
合计 | 1470 | 1600 |
解题思路
看到题目后首先关心的是如何实现数独算法,因为以前没玩过数独所以特地下了app熟悉数独的规则和解法。初步了解后打算难度适中的9阶数独入手,成功完成9阶数独的算法后再实现3、5、6、7、8阶数独算法。
接下来思考如何实现算法,想过创建三阶数组、记录每一个格子的可能数值和可能数值个数等,但是都没有深入写下去。后来上网查找数独解法相关资料看到有些熟悉DFS,回溯法,因为当初数据结构学的不太好,花了不少时间好好理解后,觉得理解后思路较简单且代码精简,就用深度优先算法来解决问题。
算法思路
//回溯法解数独
private void backTrace(int i, int j) {
if (i == m-1 && j == m) {
System.out.println("获取正确解");
outputs();
return;
}
//已经到了列末尾了,还没到行尾,就换行
if (j == m) {
i++;
j = 0;
}
//如果i行j列是空格,那么才进入给空格填值的逻辑
if (matrix[i][j] == 0) {
for (int k = 1; k <= m; k++) {
//判断给i行j列放1-9中的任意一个数是否能满足规则
if (check(i, j, k)) {
//将该值赋给该空格,然后进入下一个空格
//System.out.println( i+ " " + j + " " + k);
matrix[i][j] = k;
backTrace(i, j + 1);
//初始化该空格.
//System.out.println("初始化");
//if(find==false)
matrix[i][j] = 0;
}
}
} else {
//如果该位置已经有值了,就进入下一个空格进行计算
backTrace(i, j + 1);
}
}
核心算法完成后将其完善,添加3、4、5、6、7、8阶数独的算法,不算难,可一定要注意6、8阶数独的宫区域,区域设置及检查的宫格不能搞混!我因为这个问题有debug了几个小时。。。
if(m==6) {
int tempRow = row / 2;//区域划分每行二区、每列三区!
int tempLine = line / 3;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
if (matrix[tempRow * 2 + i][tempLine * 3 + j] == number) {
return false;
}
}
}
}
算法结束了就开始按照要求写输入输出,一开始也是懵的呀。。。cmd输入?args[]?文件读写? 然后我就网上查命令行输入,正好微信群助教也在教学了一波,舍友实例助攻,所以这个还好。再然后就是查找Java的I/O流资料,每个字都看得懂,理解起来有点难,但问题也不大,就是不太好操作。。。读入文件并填充这个属实不太好搞,而且一下子读入几个数组怎么操作
emmmm。。。后来还是参考了其他几个同学的输入。因为我一开始的想法是:把文件读入分装到inputs()函数,更具数独数n在循环里创建对象并进行回溯输出操作,一个数独稳稳当当,可在加一个就出问题了只能读取第一个数组,当时思维僵化,想半天不知道为什么烦躁的抓耳挠骚,还是询问舍友后再明白文件在循环里被重复读入,所以理所当然只能输出一个重复的答案。所以就把输入写到主函数里,没读一个数独矩阵就直接进行计算然后输出,虽然代码没有原来美观但我也没得办法。
try { // 防止文件建立或读取失败,用catch捕捉错误并打印,也可以throw
/* 读入TXT文件 */
// 绝对路径或相对路径都可以,这里是绝对路径,写入文件时演示相对路径
File filename = new File(inputFileName); // 要读取以上路径的input.txt文件
InputStreamReader reader = new InputStreamReader(
new FileInputStream(filename),"UTF-8"); // 建立一个输入流对象reader
BufferedReader br = new BufferedReader(reader); // 建立一个对象,它把文件内容转成计算机能读懂的语言
//把盘面写入数组
int ch;
int i=0; int j=0;
while ((ch = br.read()) != -1) {
if ( (((char) ch) != '\n') &&(((char) ch) != ' ')) {
if(i
测试
Code Quality Analysis
下载在eclipse中下载并配置checkstyle,进行代码质量分析
因为缩进符和含有制表符tab几乎全是黄的。。。一个个改过来了
性能分析工具Studio Profiling Tools
学习使用jdk自带的性能分析工具jconsole
心路历程和收获
心路历程:题目好难啊——我好菜呀——我是不是不适合读计算机???——不交作业就没分数,硬着头皮干吧
心态就是一直炸。。。但是确实有不少的收获,命令行输入、io流、回溯算法、GitHub仓库。学到很多东西,也不断磨练我的心态,估计下次作业我也会继续炸,但是炸多了就会习惯的吧,毕竟还有那么多次作业。。。
这次写代码我发现很关键的就是:细节决定成败。好几次卡我的点都是应为一些自我感觉不会出问题的小地方,所以一定要谨慎谨慎又谨慎。还有就是要熟悉编译软件,真的可以极大提高编程效率。[]