zoukankan      html  css  js  c++  java
  • 软工实践第二次作业——数独

    GIT地址

    估计耗费时间:


    PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划 40
    · Estimate · 估计这个任务需要多少时间 40
    Development 开发 770
    · Analysis · 需求分析 (包括学习新技术) 200
    · Design Spec · 生成设计文档 60
    · Design Review · 设计复审 (和同事审核设计文档) 30
    · Coding Standard · 代码规范 (为目前的开发制定合适的规范) 60
    · Design · 具体设计 150
    · Coding · 具体编码 150
    · Code Review · 代码复审 60
    · Test · 测试(自我测试,修改代码,提交修改) 60
    Reporting 报告 210
    · Test Report · 测试报告 150
    · Size Measurement · 计算工作量 30
    · Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30
    合计 1020

    解题思路描述:


    心路历程

    • 本来没选这门课程的,感觉挺难的,后来跟舍友纠结了几天还是在最后的截止日一起压哨选了课,选完就开始赶作业了,希望自己能在这门课中得到提升吧!拿到题目时看到数独有点小熟悉但玩的不多,看到这类题目脑海中的想法就是递归,暴力算法等等。由于自己实力有限,所以肯定会通过查阅资料和请教同学去了解一些相关的算法,通过已经完成的别班同学了解到大部分都用递归回溯,有部分用变换。由于递归也比较符合内心的灵感,所以自己就往这方面去思考。

    思路

    • 自己的想法是暴力,由于自己水平一般,所以我先试着能够生成一组数独出来,运用递归的算法,在生成的过程中,满足三个判断条件:
      • 行数字不重复,
      • 列数字不重复,
      • 宫(块)数字不重复。
    • 第一组数独生成后我开始思考如何继续生成新的数独,最后还是尝试着用简单的回溯替换但可能效率不高的方法,对最后一个数字a下手,将a删除并用[a+1,9]范围的数字替代,如果都无法形成新数独则继续往回推一个数字,按上面方法继续推导,就按这样直到找出符合的那个位置的数字,然后再对其后面的数字进行补充形成新数独。

    设计实现过程:


    • 我感觉这个算法框架还是挺好组织的,有一个判断函数,有一个生成建立函数,大体框架就有了。在我的代码里也是这样,一个judge判断函数,一个set建立函数。略显简单粗暴。
    • 具体是:
      • 判断函数里三个判断;
      • 在生成函数里我用一个变量做标记,当其等于要求个数时停止输出;
      • 首先生成一个数独;
      • 生成一个数独后主函数里面进行回溯判断继续生成新数独;

    代码说明:


    • 判断行、列、宫是否满足要求
        //行判断 
        for (i = 0; i<a; i++)
    	{
    		if (c == sudo[i][b])
    		{
    			return false;
    		}
    
    	}
    	//列判断 
    	for (j = 0; j<b; j++)
    	{
    		if (c == sudo[a][j])
    		{
    			return false;
    		}
    	}
    	//宫(块)判断 
    	m = (a / 3) * 3;
    	n = (b / 3) * 3;
    	for (i = m; i<m + 3; i++)
    	{
    		for (j = n; j<n + 3; j++)
    		{
    			if (c == sudo[i][j])
    			{
    				return false;
    			}
    		}
    	}
    
    • 生成函数
        void set(int i, int j)
        {
    	int b;
    	if (out == num)
    	{
    		return;   //数独个数达到要求个数num时停止 
    	}
    	for (b = 1; b<10; b++)
    	{
    
    		if (judge(i, j, b))
    		{
    			sudo[i][j] = b;
    			if (j<8)  //列小于8时的递归
    				set(i, j + 1);
    			if (j == 8 && i<8)  
    				set(i + 1, 0);  //列等于8时要选取新的行
    			if (i == 8 && j == 8) {
    				for (i = 0; i<9; i++)
    				{
    					for (j = 0; j<9; j++)
    					{
    						putchar(sudo[i][j] + 48);
    						putchar(' ');
    
    					}
    					putchar('
    ');
    				}
    				putchar('
    ');
    				out++;
    			}
    
    		}
    		sudo[i][j] = 0;
    	}
    
        }
    
    • 主函数
    int i = 0, j = 0, x = 2, b = 0;
    	set(i, j);
    	for (x = 2; x <= num; x++)
    	{
    		for (i = 8; i >= 0; i--)
    		{
    			for (j = 8; j >= 0; j--) //要再形成一个新数独时,用一个新的数替换原来的数,从sudo[8][8]往回判断
    			{
    				for (b = sudo[i][j] + 1; b<10; b++)
    				{
    					sudo[i][j] = b;
    					if (judge(i, j, b)) //原位置数为b,判断b+1~9能否替换原来的数
    						set(i, j);
    					break;
    				}
    			}
    		}
    	}
    

    测试运行:


    • 输入数据:

    • 输入不合法字符,输出Error:

    性能分析:


    输出部分原来我用的是cout输出,但跑起来太慢了,后来舍友建议我用putchar,速度提升了不少。
    输入100000时:

    输入1000000时:

    总结:

    • 由于在最后才选了课,所以作业有点赶,不过这个周末还是蛮充实的,一直在弄这个作业,少玩了一些游戏,少看了几场英超比赛,但内心却没有什么波澜,毕竟有舍才有得。自己水平不高弄得踉踉跄跄,不过有同学的帮忙自己不懂得地方还是可以及时求解,感谢队友们。希望自己在以后的作业中一步步提高吧。
    • PSP

    PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划 40 50
    · Estimate · 估计这个任务需要多少时间 40 50
    Development 开发 770 910
    · Analysis · 需求分析 (包括学习新技术) 200 240
    · Design Spec · 生成设计文档 60 60
    · Design Review · 设计复审 (和同事审核设计文档) 30 30
    · Coding Standard · 代码规范 (为目前的开发制定合适的规范) 60 60
    · Design · 具体设计 150 160
    · Coding · 具体编码 150 200
    · Code Review · 代码复审 60 80
    · Test · 测试(自我测试,修改代码,提交修改) 60 80
    Reporting 报告 210 240
    · Test Report · 测试报告 150 170
    · Size Measurement · 计算工作量 30 30
    · Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 40
    合计 1020 1200
  • 相关阅读:
    Android ListView 的布局图标大小设置
    Android BaseAdapter 类 重写模版
    Fabric 介绍
    CentOS yum安装mysql
    JavaStringBuffer类常用方法简介
    Java流的简单使用:读取文件、写入文件(面试题:删除注释代码)
    Android数据库详解之二:数据库用法介绍
    JavaString类的方法及说明
    Android图像识别项目OpenCV(1):技术选型以及NDK搭建
    JDK(6u25)安装及相关知识
  • 原文地址:https://www.cnblogs.com/qq805212031/p/7539330.html
Copyright © 2011-2022 走看看