• 第二次作业--数独


    github地址:https://github.com/ggrcwxh/Soft-work-practice
    编程语言 :java
    ide:eclipse java oxygen

    PSP:

    Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    计划 25 10
    估计这个任务需要多少时间 15 15
    开发 810 1010
    · 需求分析 (包括学习新技术) 100 200
    · 生成设计文档 20 10
    · 具体设计 60 60
    · 具体编码 400 500
    · 代码复审 30 40
    · 测试 200 300
    报告 200 300

    解题思路:

    《编程之美》上看到过,本来看知乎的回答(好像是java要学到什么程度可以工作)买来准备大三寒假拿块白板慢慢刷的,来学校的路上随手翻了一下,奈何c#看不懂,当小说看了。。。回来还换了台笔记本,做实践作业,考驾照,9月8号才开始做题,然后看到编程语言是c/c++/c#的时候我的内心是奔溃的。大一大二上一路划水过来加半年没用过的语言。。非常认真的搜了下如何一日内学会使用c++,答案是。。。不管了用java写不做可执行文件了反正没法用-c调用,要做可执行文件还得生成jar包加exe4j打包,不如直接导入ide,不行的话大不了开学收拾细软跑路去写接口(逃。《编程之美》上提供了两种方法。按字面意思(看不懂c#)我的理解是一种回溯,另一种我也不知道怎么称呼。搜索外加思考了一下,决定先实现第二种方法然后写gui做成游戏。第二种方法是先确定中间的九宫格,然后再交换位置确定其他八个九宫格。这样的话如果没有限定左上角是固定数的话是有9!阶乘个数独,30多万个呐。限定了左上角也有4万多个。然后加上要扣掉好多个格子,怎么算也有几百万种了,够玩了。然后再用回溯实现,因为第一题要求数独数到一百万。至于附加题第二小题,我搜索学习了一下捋了下思路,生成一个九宫格然后随机挖格子,每挖一次格子用dlx算法求解,看看是不是唯一解,不是的话重挖。我觉得以我这么烂的水平单写这个2天的时间打不住了。。先做第一第二题吧,然后看看能不能发现些更简便的方法做第三题。
    

    设计实现:

    先写游戏:这个我想法非常简单,1-9随机排序,然后加个二维数组存上面第一个图的顺序,然后按这个顺序把这9个数输出九遍就行了。。。然后加个线程按题目要求扣点空再用swing写个界面,完成。
    然后做第一题随机数加递归加走不下去了回溯然后从左往右,从上往下搜下去,一个方法递归加一个方法判断就好,其他多出来方法完全是因为java的io系统对初学者不太友好。我不知道这是不是书上说的深度优先搜索,反正是解出来了。。。
    然后第三题,我突然想到一种方法,按上面第二个图这样挖空,挖掉27个空后是唯一解,因为行限制只能是这三个数,列限制这三个数两两不能交换。再随机从不同行不同列没挖掉的数中挖三个空。目测是唯一解。。开学后有时间学下dlx算法解出来看看。三十多万种数独加上随机从60多个格子里砍掉三个格子,这样也有几百万个唯一解的数独了吧,至于数独太容易解,胎教数独,你值得拥有。
    

    关键代码分析说明:

    第一题的递归具体思路就和设计实现上的差不多用Vector存可供选择的数,然后生成随机数作为索引用Vector里的数给数独某个单元格赋值,如果可以赋值则修改line和col的值继续递归,如果不行的话就返回上一层,我自己认为比较难(因为整了我好久)就是某个位置走不通了返回到上一个位置的时候,得把上一个位置原本的数从备选项中排除出去,一开始写的就死在这上了,直接删了重写了后来。
    
    		boolean CrSduku(int line ,int col)//构造一个数独
    		{
    			Vector<Integer> current = new Vector<Integer>(0,1);
    			
    			for(int i=1;i<10;i++)
    			{
    				current.add(i);
    			}
    			if(line==0&col==0)
    			{
    				current.remove(8);
    				col++;
    			}
    			
    			while(current.size()!=0)
    			{
    				Random r1 = new Random();
    				int r=Math.abs(r1.nextInt())%current.size();//生成一个小于Vector当前组件数量的一个随机数作为Vector的index;
    				suduku[line][col]=current.get(r);
    				current.remove((Integer)current.get(r));
    				if(Suitable(line,col)==false)
    				{
    					continue;
    				}
    				if(line==8&col==8)
    				{
    					return true;//一个数独构建完成
    				}
    				if(col==8)
    				{
    					//一行填满下一行
    					col=0;
    					line++;
    				}
    				else
    				{
    					col++;
    				}
    				if(CrSduku(line,col)==true)
    				{
    					return true;
    				}
    				
    			}
    			suduku[line][col] = 0;//如果找不到合适的数返回上一层递归,即本位置的上一个位置
    			return false;
    			
    			
    		}
    

    测试运行:

    数独游戏,功能应该实现了吧,玩了半个小时暂时还没有发现bug,至于界面,Java写界面好尴尬,要不再导个substance包?(逃。

    第一题1000000测试了一遍好像可以。

    这个。。。都不知道是不是唯一解。

    性能测试图:

    用的JProfiler,莫名奇妙char[]的调用率很高,整个程序都没有使用过char,看来String只不过是基于char封装一些方法。老师要的看函数(方法)使用情况查了下应该要用tptp这个插件吧,至于为什么不使用tptp,37g。。。用先生成中间的九宫格然后改变其他九宫格应该是最快的,然后其他九宫格的排序方式应该不止《编程之美》上一种,这种方法用于实现游戏,就没写了;至于回溯那个算法想了好久,之前把用array的改成Vector,因为Vector可以直接移除组件,这样遍历的次数应该会比array少吧。改进已经新开一个随笔:http://www.cnblogs.com/wkmocr/p/7503149.html
    

    遇到的困难及解决方法:

    困难描述:io系统没人性,递归出现bug测试到腿发软。
    做过哪些尝试: 《java编程思想》+《java官方入门》+《java核心技术卷一》关于io的部分看了一遍,疯狂debug。
    是否解决: 是
    有何收获: 现在满脑子都是字节流,字符流

    第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
    1 600 600 22 22 和javaio死磕了一边

    执行力,泛泛而谈:

    执行力就是完成需求的成度吧,泛泛而谈是谈自己的认识吧,实例:比如携程最近从.net转Java的程序员?。
    

    收获:

    先给上个随笔留言的老师道个歉,没回复,暑假跑到中朝边境去了,2m网速一栋楼用,手机信号还不好。。。实在不想上网,上一篇随笔还是跑到网吧去写的。。。另外《构建之法》刚刚到写完就看。收获最大就是梳理了一遍javaio吧,然后对回溯,和Vector有了更深的了解吧。

  • 相关阅读:
    React在componentDidMount里面发送请求
    React 术语词汇表
    React里受控与非受控组件
    React和Vue等框架什么时候操作DOM
    【LeetCode】79. Word Search
    【LeetCode】91. Decode Ways
    【LeetCode】80. Remove Duplicates from Sorted Array II (2 solutions)
    【LeetCode】1. Two Sum
    【LeetCode】141. Linked List Cycle (2 solutions)
    【LeetCode】120. Triangle (3 solutions)
  • 原文地址:https://www.cnblogs.com/wkmocr/p/7501565.html
Copyright © 2020-2023  润新知