软件工程实践2017第二次作业-数独生成器
2017-09-10 22:50
267 查看
github : sudoku
一. 问题描述
阅读《构建之法》第一章至第三章的内容。随机生成n个不重复且已解答完毕的数独棋盘。
数独盘面是个九宫,每一宫又分为九个小格,在每个空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次。
数独左上角第一个数为 : (学号后两位相加)%9+1。
输出到sudoku.txt。
二. 问题分析与思考
数独每个格子的数字 num 的性质该行其他格子不出现 num。
该列其他格子不出现 num。
该宫其他格子不出现 num。
如何快速判断数字x满足上述条件可填入(r, c)格子?
循环行、列、宫判断? 太慢了.
牺牲部分空间,对行、列、宫已经出现的数字进行mark,便可快速判断了。
枚举数进行填充:
从1到9遍历枚举. (生成的数独看着一点随机性都没有)。
随机生成一个数,[1,9]之间, 以这个数为起点去枚举.(增加了数独随机性, 似乎速度上也加快了一点)。
预处理:
(r,c)对应的宫数 = ((r % 3) ? r : (r - 1)) / 3 * 3 + ((c % 3) ? c : (c - 1)) / 3 + 1;求优雅的计算方式。
(1, 1) = (学号后两位相加)%9+1。
特殊输入处理。
输出优化
使用putchar( )优化输出。
三. 代码设计流程图
![](http://chuantu.biz/t6/44/1505098626x3664417039.png)
四. 代码编写
void sudoku::dfs(int x, int y) { if (flag) return;//已经输出n个则退出搜索 int i, j; if (x == 9 && y == 9) { ++cnt; out();//输出数独矩阵 if (cnt != target) putchar('\n'); if (cnt == target) { //getchar(); flag = true; } return; } //填写下一格的数 int nx = x, ny = y + 1; if (ny == 10) ny = 1, ++nx; // 跳到下一行 int now = getgg[nx][ny]; // 第x宫 //此处由循环1-9 改成 随机生成数再进行循环 => 增加数独的随机性 int cur = rand() % 9 + 1; for (i = cur; ; ) { // 满足该行or该列or该宫不重复 if (!row[nx][i] && !cow[ny][i] && !gg[now][i]) { row[nx][i] = true, cow[ny][i] = true, gg[now][i] = true, vec[nx][ny] = i + '0'; dfs(nx, ny); row[nx][i] = false, cow[ny][i] = false, gg[now][i] = false, vec[nx][ny] = '0'; } ++i; if (i>9) i = 1; if (i == cur) break; } return; }
五. 性能分析
测试数据: 100w = 1e6CPU使用率报告
![](http://chuantu.biz/t6/44/1505052329x2918527074.png)
主要耗时在于dfs.
let us go to dfs() ↓
dfs 函数分析报告
![](http://chuantu.biz/t6/44/1505052674x2918527074.png)
上图显示, 输出数独矩阵的函数out()与枚举数占用的比例最大.
根据分析报告优化
输出部分由putchar()替换printf(), 输出明显加速
枚举起点采用随机数, 使得枚举的数尽可能早地满足条件
还存在一定的优化问题, 有待补充.
六.输出结果
![](http://chuantu.biz/t6/44/1505053309x2918527074.png)
七.单元测试及代码覆盖率
有待完成...八. PSP
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 60 |
· Estimate | 估计这个任务需要多少时间 | 30 | 60 |
Development | 开发 | 360 | 400 |
· Analysis | · 需求分析 (包括学习新技术) | 30 | 20 |
· Design Spec | · 生成设计文档 | 40 | 60 |
· Design Review | · 设计复审 (和同事审核设计文档) | 30 | 30 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 50 |
· Design | · 具体设计 | 60 | 60 |
· Coding | · 具体编码 | 60 | 60 |
· Code Review | · 代码复审 | 30 | 20 |
· Test | · 测试(自我测试,修改代码,提交修改) | 80 | 100 |
Reporting | 报告 | 60 | 60 |
· Test Report | · 测试报告 | 20 | 30 |
· Size Measurement | · 计算工作量 | 20 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | 20 |
合计 | 450 | 520 |
九. 补充
关于putchar比printf快? 2017.9.14putchar, 单字符输出,无格式控制, 速度快
printf 格式化输出, 比putchar慢.
相关文章推荐
- 软件工程实践2017第二次作业-----个人项目实战之数独
- 软工第二次作业——数独生成器
- 第二次实践作业----数独
- 软件工程实践2017第二次作业
- 软件工程实践第二次作业——个人项目实战(数独)
- 软件工程实践2017第二次作业
- 软工第二次作业---数独
- 软件工程实践2017第二次作业
- 软件工程实践2017第二次作业
- 【评分】第二次作业-数独-第一次测试成绩
- 软件工程实践2017第二次作业
- 第二次作业——个人项目实战:生成数独
- 第二次作业——数独
- 软件工程实践2017第二次作业
- 第二次作业——个人项目实战:数独
- 软件工程实践2017第二次结对作业
- 软件工程实践第二次作业 031502220 数独
- 软件工程实践2017结对项目——第二次作业
- 软件工程实践2017第二次作业
- 第二次作业------个人项目战:数独