zoukankan      html  css  js  c++  java
  • 第二次作业--数独

    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有了更深的了解吧。

  • 相关阅读:
    430flash的操作
    430单片机之定时器A功能的大致介绍
    MSP430看门狗
    430之通用异步串口通信模块
    430的启动,I/O中断
    Msp430概述
    烦躁
    12864密码锁
    单片机的动手实践篇--51单片机玩转12864
    【CSS】font样式简写(转)- 不是很建议简写
  • 原文地址:https://www.cnblogs.com/wkmocr/p/7501565.html
Copyright © 2011-2022 走看看