软工实践第三次作业_个人编程作业

0.Gtihub项目地址

GitHub传送门

1.PSP表格

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

行动效率比想象中还要低...

2.解题思路

​ 题目到手先是去仔细端详了下数独的定义,标准数独是9*9并附带九宫格限制的矩阵,而题目要求从三宫格数独到九宫格数独均要能够求解。

​ 不同宫格之间形虽有异,但质却相同,数独矩阵的成立均建立在合乎数独规则的情况下,因此选好做法处理好类型识别后求出各个宫格的结果应该并不算难。首先想到的是根据行、列、宫的限制条件进行深搜,逐格判断各个数字在相应位置的合法性,但转念一想这样做在搜索触底回溯时可能要退后很多步再用另一个数字继续搜索,不禁感觉耗时耗力。

​ 大一大二时的怠惰导致了我编程基础的薄弱,在网上查阅了众多数独解法后开始自闭,觉得自己在短时间内无法理解这些晦涩难懂的算法后还是选择用一开始想到的笨笨的解法。

​ 因为对命令行参数的使用和定义一窍不通,我选择了参考他人的解法,以此为基础根据题目需求完善输入输出和不同宫格的求解。

https://blog.csdn.net/qq_31558353/article/details/50615760

3.设计过程

3.0 类和主要函数的设计

​ 一开始想分为输入和解决&输出两个类,但因为没能处理好变量环境只定义了一个类Read。

  • Read::read_judge
    • 处理控制台读入数据,检验读入的几个参数,目前仅是简单的几种情况的检验。
    • 正确的输入格式为 Sudoku.exe -m 9 -n 2 -i input.txt -o output.txt

1793401-20190923222429259-801678004.png

  • Read::input & Read::ouput

    • 使用ifstream文件流读取文件存入类内数组,供后续解答使用。
    • 得到所有数独矩阵的解后再一并输出到指定文件夹
  • Read::dfs & Read::check

    • 深搜求解数独盘面
    • 求解过程中的合法性验证
    3.1 主程序流程图

1793401-20190923222443103-1569579255.jpg

4.关键代码

Read::dfs

temp [0] [ ] [ ]表示已从文件读入的第一个数独矩阵,dimen表示数独的类型值。

void Read::DFS(int n)                              //深搜求解,其实就是递归啦。从(0,0)位置开始逐列遍历后再逐行遍历。
{                                                  //n表示格子的位置,0 <= n <dimen*dimen 
    if (n == dimen * dimen)
    {                                              //走完所有格子后标记成功并退出
        sign = true;
        return;
    }
    if (temp[count][n / dimen][n % dimen] != 0)    //该位置已有数,跳过
    {
        DFS(n + 1);
    }
    else
    {
        for (int i = 1; i <= dimen; i++)            //对1 -> dimen逐个填入验证
        {
            if (Check(n, i) == true)             
            {
                temp[count][n / dimen][n % dimen] = i; //数i在该位置合法,填入
                DFS(n + 1);                            //继续下一个位置的验证
                if (sign == true)
                {
                    return;
                }
                temp[count][n / dimen][n % dimen] = 0;//后续无解并返回当前位置,将原先赋值的i清空,尝试下一个数并继续往后搜索
            }
        }
    }
}
Read::check
bool Read::Check(int n, int key)
{
    int col = n % dimen;//列坐标
    int row = n / dimen;//行坐标
    for (int i = 0; i < dimen; i++)
    {
        if (temp[count][row][i] == key)//检查行正确性
            return false;
    }
    for (int i = 0; i < dimen; i++)
    {
        if (temp[count][i][col] == key)//检查列正确性
            return false;
    }
    if (dimen == 3 || dimen == 5 || dimen == 7)
    {
        //3,5,7宫格只需判断行与列的合法性
        return true;
    }
    switch (dimen)
    {                         //根据所给宫格定义取出当前所在宫格的左上坐标,并遍历宫内格子
    case 4: {
        int x = n / 4 / 2 * 2;
        int y = n % 4 / 2 * 2;
        for (int i = x; i < x + 2; i++)
        {
            for (int j = y; j < y + 2; j++)
            {
                if (temp[count][i][j] == key)
                    return false;
            }
        }break;
    }
    case 6: {
        int x = n / 6 / 2 * 2;
        int y = n % 6 / 3 * 3;
        for (int i = x; i < x + 2; i++)
        {
            for (int j = y; j < y + 3; j++)
            {
                if (temp[count][i][j] == key)
                    return false;
            }
        }break;
    }
    case 8: {
        int x = n / 8 / 4 * 4;
        int y = n % 8 / 2 * 2;
        for (int i = x; i < x + 4; i++)
        {
            for (int j = y; j < y + 2; j++)
            {
                if (temp[count][i][j] == key)
                    return false;
            }
        }break;
    }
    case 9: {
        int x = n / 9 / 3 * 3;
        int y = n % 9 / 3 * 3;
        for (int i = x; i < x + 3; i++)
        {
            for (int j = y; j < y + 3; j++)
            {
                if (temp[count][i][j] == key)
                    return false;
            }
        }break;
    }
    }
    return true;
}

5.样例测试

六宫格

1793401-20190923222455678-1772233189.png

七宫格

1793401-20190923222508245-1021447283.png

八宫格

1793401-20190923222513759-1825482653.png

九宫格

1793401-20190923222519231-2099175986.png

因三宫格与五宫格同七宫格解法相同,四宫格与九宫格相似,便不再依次po出。

6.性能分析

1793401-20190923222346469-1550651105.png

找到传参启动的性能分析页面,然后,白给了?

1793401-20190923222401362-1350768970.png

也不知道是程序还是使用过程不恰当的问题.....抓紧时间完善吧

7.心路历程和收获

​ 对于没有系统完成项目的经验的我来说这次作业难在相关工具的使用和理解上。百度是我的好老师,秉承着不懂就查的想法也算是有所收获,但对于有效信息的分辨和筛选还是经验不足。这次作业算是摸了,性能检测实在没辙,自己已经想不到解决的出路。

​ 收获的话算是巩固了下对文件的写读理解,刚好配合最近一起进行的linux课程学习文件流读写。工具使用的话算是初窥VS门径,github的常用操作已经完全理解了。

转载于:https://www.cnblogs.com/NiftyChen/p/11575360.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值