• 软件工程实践第二次作业


    github地址: https://github.com/Kaloneme/sudoku.git

    解题思路分析

    刚刚接触到这个题目的时候,就想到了二维数组跟回溯法(虽然不是很熟练),但是从一开始我对数独有个误区,就是宫中不能重复这个问题,我的认知中9x9的数独表中不只有九个宫(之前没了解清楚),而是每9个在一起的格子就是一个宫,这无疑给我添加了巨大的麻烦。后来在跟同学探讨的过程中,他告诉我就只有9个宫,让我的心情一下子放松下来(虽然后面才知道原来代码不是最难过的)。
    然后我的思路是先分开宫,然后一行一行填,一个一个填过去,每填一个就检查一次该行、该列、该宫是否有这个数字,要是遇到死胡同,就利用回溯法退回重新。
    

    设计过程

    语言:c、c++

    1.标记函数与初始数独表

    int table[11][11];        //数独表 
    	int palace[11][11];      //宫标记 
    	int line[11][11];       //行标记 
    	int list[11][11];      //列标记
    	int  seat[11][11];   //该位置所属的宫 
    
    • table是初始表,而palace、line、list都是标记位,seat是点(i,j)位置所属的宫。设计的过程中很容易把数组的值到底表示的是什么搞混了,写着写着就突然混了一下概念,所以我认为之前在纸上的准备很重要,随时可以让你回归最初的概念,比较好分清楚这些东西。

    2.初始化函数(给每个位置标记上该位置所属的宫)

    shudu::shudu()
    {
    	memset(table, 0, sizeof(table));
    	memset(line, 0, sizeof(line));
    	memset(list, 0, sizeof(list));
    	memset(palace, 0, sizeof(palace));
    	
    	flag = false;
    	sum = 0;
    	for (int i = 1; i <= 9; i++)
    	{
    		for (int j = 1; j <= 9; j++)
    		{
    			int row = (i - 1) / 3;
    			int cow = (j - 1) / 3;
    			seat[i][j] = row + cow * 3 + 1;     //标记宫 
    		}
    	}
    	
    }
    
    • 最初的想法是把宫分类,然而怎么把分好类的宫与每个位置对应上呢?要是对应上了,这样对于宫是否重复的判断就提供了极大的便利,最后就有了seat二维数组,并且有了这个推算每个位置所属的宫的算式,方便了之后的宫判断,极大的简化了代码的复杂度,顺便把初始表table与其他标记数组初始化。

    3.生成数组表(fillNumber()函数)

    /*
     利用fillNumber算法,从第二个填起,生成1-9的随机数,每填一个都检查一次是否与
     所填的位置的宫、行、列有重复,没有重复就继续,若有重复则将此数加1继续尝试,
     填到最后一位时若不符合则逐一退回,直到完成数独表。 
    */ 
    void shudu::fillNumber(int x, int y)
    {
    	if (flag)return;
    	if (x < 9 || y < 9){
    		int a = x;
    		int b = y + 1;
    		if (b>9)
    		{
    			b = 1;
    			a++;
    		}
    		int p = seat[a][b];        //p来表示现在所属的宫
    		int them = rand() % 9 + 1;   //产生随机数 
    		int k = them;
    		while (1){
    			if (!line[a][k] && !list[b][k] && !palace[p][k]){        //若没出现过则都为0 
    				table[a][b] = k, line[a][k] = 1, list[b][k] = 1, palace[p][k] = 1;
    				fillNumber(a, b);
    				table[a][b] = 0, line[a][k] = 0, list[b][k] = 0, palace[p][k] = 0;
    			}
    			k++;
    			if (k == 10)k = 1;
    			if (them == k)break;	           //退回 
    		}	
    	}
    	else{
    		sum++;
    		int i, j;
    		for (i = 1; i <= 9; i++){
    			for (j = 1; j <= 9; j++){
    				cout << table[i][j];
    				if (j < 9)cout << " ";
    			}
    			cout << endl;
    		}
    		if (sum != n)cout << endl;
    		if (sum == n)flag = true;              //输出n个数独表后结束 
    	}
    }
    
    • 这里利用fillNumber函数生成整个数独表,在这里,这些用于标记的数组派上了很大的用场。刚开始对于回溯法其实还不是很顺手,在同学的帮助下,才能是顺利的写出了这个算法。不过最后还是遇到一些问题,通过不断插入输出的办法,终于找到问题所在(个人感觉这办法还是很好用的)。不过在这个过程中我了解到自己的薄弱点的所在,虽然知道用这种方法,但是却用不熟悉,还是同学的帮助让我完成了,所以今后,一定要加大码量,加强练习。

    性能测试分析

    如下图:

    • 这是用cout输出的结果,数组table使用int型,却用了快要两分钟,cpu测试达到了100000。

    • 这是用putchar输出的结果(听同学说用这个会比较快),数组table使用char类型,只用了29秒,cpu测试达到14000+,这也差太多了,有点搞不懂。

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

    总结

    • 这次的作业真是突如其来,让我的暑假如此收尾,跟期末一般。说到这次的作业,代码倒不是很难,但是后续的一些工作简直让人发疯,都没有接触过,要下好多插件,最气的是下完后还是没成功。
      总的来说还是对这些工具不熟悉,有些是见过没用过,有些是没见过没用过,总之就是很生疏。有点哀伤。
  • 相关阅读:
    APIO2020 粉刷墙壁
    上传文件超过1MB时,前端直接返回500,没有进入到上传方法
    mybatis xml 文件中 判断条件为时间,则不能做空字符串判断,否则会报错
    springcloud 多模块自动化部署 (Cloud Toolkit)
    @RequestBody Content type 'multipart/form-data;boundary=----WebKitFormBoundarybEyHr0FZTTOHW7Vq;charset=UTF-8' not supported
    读取视频时长
    zuul中使用Configuration注解后,过滤器无响应
    IDEA 2020.1 无法点击表名链接到数据源
    IDEA 常用插件
    转账到支付宝账户
  • 原文地址:https://www.cnblogs.com/Kaloneme/p/7501442.html
Copyright © 2020-2023  润新知