软件工程——数独 总结报告
开发环境
- Windows10 版本号1903
- VS2019 16.3.2
- Intel vtune Profile 2020
- Microsoft. CodeAnalysis. FxCopAnalyzers 2.9.8
- 测试覆盖率工具opencppcoverage
- RAM 16GB 3200MHz 三星
- AMD Ryzen 7 2700X 3.90GHz
- SSD 三星 MZVLB1TOHALR-00000
相关地址
源代码仓库:https://gitee.com/wangzhankun/software_engineering_sudoku
博客地址: 软件工程博客 (所有的博客目录)
可执行文件地址:可执行文件
相关软件配置项请查看相关目录下文档。主要编写了软件需求规格说明书、软件设计、软件测试说明、编码风格要求等文档。
博客只是大致记录了我的开发过程,所有的各个项目的总结工作以及算法设计等都在相关的软件配置项的文档中。
需求分析疑惑
这方面的内容在需求分析中也做了说明, 为避免老师没有看到,在这里特别粘贴出。
换行问题
关于输出和输入文件格式有所不清楚,没有明确说明最后一个数独的格式。即,最后一个数独的最后一个数字输出之后是否有换行字符。
由于无法与用户进行及时沟通,本程序采取最后一个数字后无换行字符的形式,即要求输入和输出文件中最后一个数独的最后一个数字后面没有换行字符。
换行字符问题
用户对于文件的换行字符没有进行详尽说明,文件换行字符才有CRLF格式还是其他格式。本程序按照换行为双字符的CRLF或者是单字符的LF进行设计,即可同时支持两种格式。
文件保存位置问题
另外关于原文要求数独输出文件与程序所在位置与使用相对路径的表述是相互矛盾的。即,如果命令行所在位置与程序所在位置不一致,若是使用相对路径则输出文件sudoku.txt不会在与程序所在位置相同的目录。正确的做法应当是在程序中编写相关的过程获取程序所在位置与sudoku.txt文件名组成绝对路径进行覆盖创建。
覆盖问题
原文中没有描述当用户输入命令错误时是否对sudoku.txt进行覆盖,这里选择不覆盖。
PSP2.1
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
* Estimate | * 估计这个任务需要多长时间 | 30 | 45 |
Development | 开发 | ||
* Analysis | * 需求分析(包括学习新技能) | 240 | 300 |
* Design Spec | * 生成设计文档 | 20 | 120 |
* Design Review | * 设计复审(和同事审核设计文档) | 0 | 60 |
* Coding Standard | * 代码规范(为目前的开发指定合适的规范) | 40 | 30 |
* Design | * 具体设计 | 30 | 240 |
* Coding | * 具体编码 | 180 | 360 |
* Code Review | * 代码复审 | 60 | 60 |
* Test | * 测试(自我测试、修改代码、提交修改) | 60 | 240 |
Reporting | 报告 | ||
* Test Report | *测试报告 | 60 | 60 |
* Size Measurement | * 计算工作量 | 30 | 30 |
* Postmortem & Process Improvement Plan | * 事后总结,并提出过程改进计划 | 60 | 60 |
Total | 合计 | 810 | 1605 |
目录说明
文件中的xml是绘制图形工具生成的,可以使用draw.io进行打开,不可以选择打开网页文件,只能下载之后再打开。
.
├── LICENSE
├── README.md
├── suduku_without_gui
│ ├── BIN
│ │ ├── IntegrationTest.exe//测试文件,后面再用户手册中进行讲解
│ │ └── sudoku.exe//目标文件
│ ├── gtest//Google Test工程文件
│ │ ├── share.h
│ │ ├── test_interpretor.cpp
│ │ └── test_SudokuChecker.cpp
│ ├── suduku_without_gui//主工程文件
│ │ ├── header.cpp
│ │ ├── header.h
│ │ ├── interpretor.cpp//进行命令解析
│ │ ├── interpretor.h
│ │ ├── packages.config
│ │ ├── SudokuChecker.cpp//对数独进行检查
│ │ ├── SudokuChecker.h
│ │ ├── SudokuMaker.cpp//生成数独
│ │ ├── SudokuMaker.h
│ │ ├── SudokuPrinter.cpp//输出数独至文件
│ │ ├── SudokuPrinter.h
│ │ ├── SudokuReader.cpp//从文件读取数独
│ │ ├── SudokuReader.h
│ │ ├── SudokuSolver.cpp//对读入的数独进行求解
│ │ ├── SudokuSolver.h
│ │ ├── suduku_without_gui.cpp//主函数
│ │ ├── test.cpp//模块测试问价
│ │ └── test.h
│ └── test_SudokuMaker//集成测试工程
│ ├── RepeationTest.cpp//重复性测试
│ ├── RepeationTest.h
│ ├── SudokuProblemMaker.cpp//生成数独问题
│ ├── SudokuProblemMaker.h
│ └── test_main.cpp//主函数
├── 代码规范.md
├── 软件工程基础 - 个人项目.pdf
└── 软件配置项
├── 结构化设计
│ ├── 混合分析法.xml
│ ├── 软件设计规格说明书.docx
│ ├── 详细设计.html
│ └── 详细设计.xml
├── 软件测试
│ ├── 代码分析
│ │ └── 代码分析报告.docx
│ ├── 单元测试与模块测试
│ │ ├── 代码覆盖率测试.docx
│ │ ├── 命令解析模块测试.xlsx
│ │ ├── 数独检查模块测试.xlsx
│ │ └── 数独生成算法测试.docx
│ ├── 集成测试
│ │ ├── 集成测试2.docx
│ │ └── 集成测试.docx
│ ├── 软件测试说明.docx
│ └── 性能测试
│ └── 性能测试分析.docx
└── 需求分析
├── DFD.xml
├── 软件需求规格说明书v1.0.docx
└── 软件需求规格说明书v1.1.docx
12 directories, 46 files
用户手册
在BIN目录下有两个可执行文件,其中sudoku.txt完全按照老师要求进行编程,支持参数为-c, -s,参数说明如下:
sudoku.exe -c NUM//1<=NUm<=1e6,在同目录下生成NUM个数独到sudoku.txt文件中
sudoku.exe -s path//path为问题数独的路径,求解数独并将结果输出到同目录的sudoku.txt文件中
IntegrationTest.exe是我为方便个人进行测试而编写的一个文件,使用操作如下:
IntegrationTest.exe -c path//读取path文件,对其中的数独进行重复性测试,哈希算法快速计算1e6
IntegrationTest.exe -s path1 path2//从path1中读取数独进行挖空,输出到path2中
总结
解题思路
在刚刚拿到题目的时候就想着这道题目应该有往年的学长做过,就上网搜索类似的项目。查看了几个项目的博客,对该题目有了一定的理解和思路。于是将题目分解为了三大块即命令解析,数独生成和数独求解。其他诸如文件读入输出等为配套模块。
其中,在与同学的交流过程中找到了数独生成的快速算法;在上网查找资料的过程中意外发现了数独求解的快速算法。
关于文件IO没有使用C++的库函数,而是采用了我在操作系统实验课上学到的调用Windows内核API,这样进行文件IO的操作速度应该是由于C++函数库的。问题就是由于输入输出是块操作,因此有些问题,对文件格式极为敏感。
其他博客撰写要求4请查看需求分析和软件设计文档,5请查看性能测试分析文档. 关键代码分析已实现中进行了注释,配合结构设计文档进行查看。
收获
在做软件工程数独作业的过程中,基本走了需求分析、软件设计、软件设计三大步骤,掌握了软件工程的基本思想。通过尽可能像规范化的软件项目靠拢,认识到了软件工程对软件设计和实现的巨大帮助。深切体会到了软件工程方法学的强大。
在编码之处,我依照原来的思路,一心想要编程,但是效果并不好,对代码进行了反复修改和设计。但是后来通过对算法的详细设计和修改,之后再进行编程,发现编程真的仅仅是实现的过程,体会到了软件需求分析和软件设计在软件实现上的
巨大作用。
参考资料
项目参考
百度 软件工程数独 即可
数独求解算法
https://blog.csdn.net/huang826336127/article/details/68958379