软工实践2019第三次作业

软工实践2019第三次作业

1. 【Github项目地址】

2. 【PSP表】

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

3.【 解题思路描述】:借鉴一下人为解数独的过程,把它用代码实现。

最贴近的便是:
  • 先遍历输入数据,找出所有为0的可填区域。
  • 在按一定顺序(可以直接按行遍历整个盘面)标记所有可填区域的可填数字(它所在行所在列及所在宫格已填数字标记为0,可填则标记为1),并按从少到多入队列。
  • 从最少可填数字开始填写,并更新所在行、列及宫格的可填区域的可填数字,直到最后可填区域都填完则返回输出解。

    由此看来,此思路适合1只有一解的情况。

4. 【设计的实现过程】:由于本人不太会写类(太菜了,编程没学进去,还是舍友教我怎么写的这段面向过程程序),所以写了3个函数实现,分别是标记可填数字,递归处理求解,输出函数。单元测试没做,而且代码没考虑宫,所以只能解决没有宫的3、5、7阶(有bug……不知道怎么调试了...3阶的不知道有没有)仅有一解(多解也只输出一解)数独,而且输入得严格按照作业要求,没有设置容错性分析。

5. 【改进性能】本次作业我写的(应该是舍友和我)代码写完测试后就没优化了,所以性能改进并没有去做。我是按行列顺序遍历深搜的,因为发现按可填数目最少优先求解太麻烦了,不知道怎么实现。

6. 【代码说明】

  • 定义全局变量。
int m, n, ans[9][9];//m-宫格阶级(3~9的整数);n-待解答盘面数目;ans-存放解的数组
bool solved[10];//标记是否得到解
int B = 0;//第几盘
fstream fr, fw;//定义输入输出对象
  • 标记(x,y)格子可填数字——x,y从0到m-1取值
/*标记当前格子可填数字*/
void mark_avai(int x, int y, int(*arr)[9], int *q)
{
    int i(0);
    while (i < m + 1)q[i++] = 1;//q数组初始化为1,表示1~m为可填数字
    for (i = 0; i < m; ++i)
    {
        q[arr[x][i]] = 0;//遍历当前格子所在列,并标记q[列的值]=0,表示当前格子无法填该值
        q[arr[i][y]] = 0;//遍历当前格子所在行,并标记q[行的值]=0,表示当前格子无法填该值
    }
}
  • 定义输出函数。
/*输出函数,方便处理时输出,u为阶数*/
void fileout(int(*arr)[9], int u)
{
    for (int i = 0; i < u; ++i)
    {
        for (int j = 0; j < u; ++j)
            fw << arr[i][j] << " ";//输出一行的值并用空格隔开
        fw << endl;//换行
    }
    fw << endl;//输出完一个盘面的解后换行
}
  • 深搜计算求解。
/*通过递归,求解数独函数,u为阶数*/
void deal(int(*arr)[9], int u, int x, int y)
{
    if (y == u)
    {
        y = 0;
        ++x;
    }//如果列号等于阶数则处理下一行
    if (arr[x][y] != 0) //如果当前格子数值不为0
    {
        if (x == u - 1 && y = u - 1) //最后一个格子
        {
                    fileout(arr, m);
            return;
            
        }//处理完后便退出
        else
        {
            deal(arr, u, x, y + 1);
        } //continue
    }
    int mark[10]; //存放函数mark_avai中q数组的值
    int record = arr[x][y]; //记录传入数组的值
    mark_avai(x, y, arr, mark); //调用函数,获取当前格子(x,y)可填数字
    for (int k = 1; k <= u; ++k)
    {
        if (mark[k] == 0)continue; //如果当前值k不可填则进行k+1判断
        arr[x][y] = k; //mark[k]=1,说明当前格子(x,y)可以为k
        if (x == u - 1 && y == u - 1) //为最后一个格子
            fileout(arr, m), solved[B] = true;//将解输出到文件
        else deal(arr, u, x, y + 1); //非最后一个格子则继续处理下一个格子
        if (solved[B])return; //如果获得解则退出函数
    }
    arr[x][y] = record;//还原传入数组的值
}
  • 命令行处理。(太菜了,查了这么久只知道这样子处理)
int main(int argc,char *argv[])
{
    m = atoi(argv[2]); 
    n = atoi(argv[4]); 
    fr.open(argv[6], ios::in); //读入输入文件
    fw.open(argv[8], ios::out); //打印输出文件
......
}

7. 【构建之法学习心得】

    哎,这么久过去了,书只是浏览了一半左右,并没有认真阅读,直到博客说认真阅读前三章才知道自己已经忘记了这本的具体内容,现在看这本书也宛如第一次看一样,没有丝毫印象。本书最大的特色就是举例了许多对话还告诉读者某个知识点的作用;还有就是语言朴素易理解。大概只记得书中提了代码规范,还好笔者一直都是那样码代码的(虽然没写过多少代码);还有就是结对编程。要说心路历程和收获还是等在用心读读再谈吧。整体上看,本书讲的是如何构建一个·软件及软件开发流程及软件工程理论、技术。差不多就这样子了吧......Bye......下次再见。
PS:

软工实践2019第三次作业_第1张图片

你可能感兴趣的:(软工实践2019第三次作业)