软工我的项目git
https://github.com/Lydia-yang/2017BUAA-SoftwareEngineeringgithub
在刚开始拿到题目的时候,关于生成数独终局,个人思路是能够随机生成数而后选择适合的数填满便可获得,后来经过上网查找一些数独生成算法,发现能够经过必定的顺序来减小工做量,好比将1到9个数字依次随机填入3*3的宫格里,或者记录每次每次尝试的数避免重复,还有初始化对角线的3个3*3的宫格,或者依次填入1到9等。最后选定了将1到9个数值依次填入3*3的宫格里这种算法,也就是这篇博客的算法。
将数独分为9小块,将1-9按照必定序列填写1-9小块,好比先将1填入1号小块,再填入2号小块,知道填完9号小块,再填2与1同样,遍历全部数便可获得一个生成数独。
至于解数独,思路与生成数独差很少,也是回溯,可是是对于每个没有填的位置试全部可能的数字。算法
实现个人算法,首先,要有一个存储九宫格的二位数组,出于考虑,我建立了一个数独类,这个类里有相应的行列及3*3小块的重复检查,以及插入和删除,因为我解决数独和生产数独用的是不一样的方法来插入数字的(一个是肯定数字选位置,一个肯定位置选数字),因此有两种插入的方法,而后就是打印数独的方法。
在处理命令行中,有判断-c后面接的是不是正整数的函数,一样,生成数独和解数独都有各自的函数,解数独是经过文件读入的,所以也设定了一个处理文件读入函数,在后面优化的过程当中,又新增了输出到文件的函数,单元测试主要是将produce和solve这两个函数测试了一遍。下图是函数类之间的关系:数组
一开始生成数独时,几分钟都没出结果,后来通过性能分析,以下图:
函数
发现是输出占了大多数时间,后来作了优化,将输出结果先输出到一个字符数组里,再所有一块儿输出,最后的性能分析以下:
post
下面这段代码是用来解数独的,其中输入表明的含义为:性能
对于每一次执行,将这个空位子插入数字,并标记已经试过的数字,最后完成时输出,每次回溯时都清空当前位置。单元测试
void solve(sudoku sudo, int x[], int y[],int total, int & count, char *str, int &count_s) { int marked[9] = { 0 };//用来标记数字是否已经选过 int new_count = count; while (true) { int now = sudo.insert(1, x[new_count], y[new_count], marked);//在空位子插入数字 if (now < 0) return; else marked[now-1] = 1; if (new_count == total - 1) {//最后一个 sudo.printsudoku(str, count_s);//打印数独 return; } count = new_count + 1; solve(sudo, x, y, total, count, str, count_s);//下一个 if (count == total - 1) return; sudo.del(1, x[new_count], y[new_count]); } }
下面这段代码是用来生成数独的,其中输入表明的含义为:测试
对于每一次执行,将这个数字插入当前3*3小块空的位置,并标记已经试过的位置,最后完成时输出,每次回溯时都清空当前位置。优化
void produce(int total, int nums[], int block_num, int & count_total, int count_nums, sudoku s, char *str, int &count_s) { int marked[9] = { 0 };//标记已经试过的位置 int new_block_num, new_count_nums; while (true) { new_block_num = block_num + 1; new_count_nums = count_nums; int now = s.insert(nums[new_count_nums], new_block_num, marked); if (now <0) return; else marked[now] = 1; if (new_block_num == 9) { if (new_count_nums < 8) { new_count_nums=count_nums+1; new_block_num = 0; } else {//填写至最后一个 count_total++; s.printsudoku(str, count_s);//打印数独 s.del(0, new_block_num, now); return; } } produce(total, nums, new_block_num, count_total, new_count_nums, s, str, count_s); if (count_total == total) return; s.del(0, new_block_num, now); } }
Psp | personal software progress stages | 预估耗时 | 实际耗时 |
---|---|---|---|
planning | 计划 | 20 | 30 |
estimate | 估计这个任务须要多少时间 | 10 | 10 |
development | 开发 | 480 | 600 |
analysis | 需求分析 | 10 | 10 |
design spec | 生成设计文档 | 30 | 35 |
design review | 设计复审 | 0 | 0 |
coding standard | 代码规范 | 10 | 15 |
design | 具体设计 | 60 | 70 |
coding | 具体编码 | 240 | 300 |
code review | 代码复审 | 120 | 130 |
test | 测试 | 240 | 300 |
reporting | 报告 | 20 | 18 |
test report | 测试报告 | 20 | 10 |
size measuring | 计算工做量 | 5 | 3 |
postmortem & process improvement plan | 过后总结,提出过程改进计划 | 20 | 20 |
合计 | 1285 | 1551 |