[2017BUAA软工]个人项目
软工个人项目
一、Github项目地址
https://github.com/Lydia-yang/2017BUAA-SoftwareEngineering
二、解题思路
在刚开始拿到题目的时候,关于生成数独终局,我的思路是可以随机生成数然后选择适合的数填满即可得到,后来通过上网查找一些数独生成算法,发现可以通过一定的顺序来减少工作量,比如将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这两个函数测试了一遍。下图是函数类之间的关系:

## 四、性能改进
一开始生成数独时,几分钟都没出结果,后来经过性能分析,如下图:

发现是输出占了大多数时间,后来做了优化,将输出结果先输出到一个字符数组里,再全部一起输出,最后的性能分析如下:

## 五、代码说明
下面这段代码是用来解数独的,其中输入代表的含义为:
- sudoku sudo, 存储待解的数独
- int x[], 所有为空位置的x值
- int y[], 所有为空位置的y值
- int total, 空位子的总数
- int & count, 用来记录目前已经填了多少空位子
- char *str, 字符数组用来储存需要打印的数独
- int &count_s, 用来标记字符数组的元素个数
对于每一次执行,将这个空位子插入数字,并标记已经试过的数字,最后完成时输出,每次回溯时都清空当前位置。
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]);
}
}
下面这段代码是用来生成数独的,其中输入代表的含义为:
- int total, 最终需要生成数独的总个数
- int nums[], 1-9的序列用来规定遍历数的顺序
- int block_num, 标记当前的3\*3的块号
- int & count_total, 用来标记当前已经生成的数独个数
- int count_nums, 用来标记当前对于nums的元素位置
- sudoku s, 当前已经填好一些空的数独
- char *str, 字符数组用来储存需要打印的数独
- int &count_s, 用来标记字符数组的元素个数
对于每一次执行,将这个数字插入当前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
| 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 |
[2017BUAA软工]个人项目的更多相关文章
- [2017BUAA软工]结对项目
软工结对项目 一. Github项目地址 https://github.com/crvz6182/sudoku_partner 二. PSP表格 Psp personal software progr ...
- [2017BUAA软工]个人项目:数独
一.项目地址 https://github.com/Slontia/Sudoku 附加作业(GUI):https://github.com/Slontia/SudokuGUI 二.开发时间 PSP2. ...
- 2017BUAA软工个人项目之数独生成与求解
1.项目GitHub地址:https://github.com/ZiJiaW/Soduko (由于一开始把sudoku看成了soduko,于是名字建错了,读起来可能有点奇怪…) 2.项目PSP表格如下 ...
- [2017BUAA软工]结对项目-数独程序扩展
零.github地址 GitHub地址:https://github.com/Liu-SD/SudoCmd (这个地址是命令行模式数独的仓库,包含了用作测试的BIN.DLL核心计算模块地址是:http ...
- [2017BUAA软工]结对项目:数独扩展
结对项目:数独扩展 1. Github项目地址 https://github.com/Slontia/Sudoku2 2. PSP估计表格 3. 关于Information Hiding, Inter ...
- [2017BUAA软工]个人项目心得体会:数独
心得体会 回顾此次个人项目,感受比较复杂,最明显的一点是--累!代码编写.单元测试.代码覆盖.性能优化,环环相扣,有种从作业发布开始就一直在赶DDL的感觉,但是很充实,也学习到和体验了很多东西.最令人 ...
- [2017BUAA软工助教]个人项目小结
2017BUAA个人项目小结 一.作业链接 http://www.cnblogs.com/jiel/p/7545780.html 二.评分细则 0.注意事项 按时间完成并提交--正常评分 晚交一周以内 ...
- [2017BUAA软工助教]个人项目准备工作
BUAA软工个人项目准备工作 零.注册Github个人账号(你不会没有吧..) 这是Git的使用教程: http://www.cnblogs.com/schaepher/p/5561193.html ...
- [2017BUAA软工助教]第0次作业小结
BUAA软工第0次作业小结 零.题目 作业链接: This is a hyperlink 一.评分规则 本次作业满分10分: 按时提交有分 一周内补交得0分 超过一周不交或抄袭倒扣全部分数 评分规则如 ...
随机推荐
- dispatchTouchEvent
View /** * Pass the touch screen motion event down to the target view, or this * view if it is the ...
- MyCat不适用场景(使用时避免)
1.非分片字段查询 Mycat中的路由结果是通过分片字段和分片方法来确定的.例如下图中的一个Mycat分库方案: · 根据 tt_waybill 表的 id 字段来进行分片 · ...
- 使用intellij idea搭建spring-springmvc-mybatis整合框架环境
使用intellij idea搭建spring-springmvc-mybatis整合框架环境 1.打开idea,创建maven项目,File-New-Project 2.选择Maven,勾选Cr ...
- Qt 编程指南10 QImage Mat QPixmap转换
//示例 pushButtonOpenPicBig按钮clicked单击动作触发 void Qt_Window::on_pushButtonOpenPicBig_clicked() { strin ...
- 安装webpack和webpack打包(此文转自Henery)
Henery博客地址为:http://blog.csdn.net/henery_002 写的很详细,可以做参考 最近要做项目优化了,尤其是前端这块,许多js需要模块化管理和相应的优化 1.输入如下地址 ...
- Qt+QGIS二次开发:自定义类实现查询矢量数据的属性字段值(图查属性)
在GIS领域,有两种重要的查询操作,图查属性和属性查图. 本文主要介绍如何在QGIS中通过从QgsMapToolIdentify中派生自定义类实现查询矢量数据的属性字段值(图查属性). 重点参考资料: ...
- <<linux device driver,third edition>> Chapter 3:Char Drivers
The Internal Representation of Device Numbers Within the kernel,the dev_t type(defined in linux/type ...
- PAT A1147 Heaps (30 分)——完全二叉树,层序遍历,后序遍历
In computer science, a heap is a specialized tree-based data structure that satisfies the heap prope ...
- 【Codeforces 1110E】Magic Stones
Codeforces 1110 E 题意:给定两个数组,从第一个数组开始,每次可以挑选一个数,把它变化成左右两数之和减去原来的数,问是否可以将第一个数组转化成第二个. 思路: 结论:两个数组可以互相转 ...
- LOJ540 游戏 构造
传送门 题意:给出$N$,试构造一个点数小于$500$的图,使得其中三元环的个数恰好为$N$.$N \leq 2 \times 10^6$ 首先构造一个尽可能大的完全图,然后在这个完全图旁边加点.尽可 ...