• 软件工程实践2019第三次作业


    Github地址:https://github.com/1hurricane/021700913

    psp

    PSP2.1 Personal Software Process Stages 预估耗时(小时) 实际耗时(小时)
    Planning 计划 1 1
    Estimate 估计这个任务需要多少时间 22 29
    Development 开发 2 2
    Analysis 需求分析 (包括学习新技术) 2 3
    Design Spec 生成设计文档 1 1
    Design Review 设计复审 1 1
    Coding Standard 代码规范 (为目前的开发制定合适的规范) 2 1
    Design 具体设计 2 2
    Coding 具体编码 3 5
    Code Review 代码复审 1 3
    Test 测试(自我测试,修改代码,提交修改) 2 5
    Reporting 报告 2 2
    Test Repor 测试报告 1 1
    Size Measurement 计算工作量 1 1
    Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 1 1
    合计 22 29
    #解题步骤 总共分成三部分,第一个就是解数独核心算法:回溯法,起到遍历的作用;第二个就是回溯算法里面包含一个函数用来判断数字合法性;第三个就是文件读写操作。 ##1.我要解数独 看到题目核心就是解数独嘛,我一看这感觉跟之前做走迷宫的题差不多,就遍历嘛,一直试,不行回头,所以核心算法的话当时就想到回溯法。 ###核心算法 ``` void SolveSudoku(int i, int j)//从a【0】【0】开始一个一个试 { if (i >= m) { for(int j1=0;j1=m的时候说明,一计算完数独。打印即可。

    if (j >= m)
    {
    SolveSudoku(i + 1, 0);
    }//j>=m的时候说明当前的行已经匹配完成。

    if (Sudoku[i][j] == 0)
    {
    for (int num = 1; num <= m; num++)
    {
    if (isValid(i, j, num))//判断num合法性
    {
    Sudoku[i][j] = num;//回溯算法一定要保留现场和恢复现场。这样下次计算不会出现问题。
    SolveSudoku(i, j + 1);
    Sudoku[i][j] = 0; //【i】【j+1】不满足时退回来,说明此时【i】【j】不满足,置零重新开始
    }
    }
    }
    else if(i<m&&j<m)//判断是否到最后一个了
    SolveSudoku(i, j + 1);

    }

    ##2.文件读写操作和命令行参数
    其实以前没怎么用过文件读写操作,基本都是编译运行就没了(我真是太菜了),然后就一脸懵逼,开始百度,问同学,怎么导入文件,写入文件,然后就是多个盘怎么读入,想不到什么好的方法(主要还是读取操作不熟,不知道有什么方便的操作),我就一次性全读出来,然后根据参数n来分别对几个盘操作。代码中m,n是全局变量,这个开始没设置好,导致不能传参数给SolveSukoku函数,调试了很久。
    

    int main(int argc,char argv[])
    {
    m=
    argv[2]-48;
    n=*argv[4]-48;
    char a[1000],p;

    ifstream infile;
    infile.open(argv[6]);
    outfile.open(argv[8]);
    int i=0;
    while(!infile.eof())
    {
    infile.get(p) ;
    if('0'<=p&&p<='9')
    {
    a[i]=p;
    i++;
    }
    }
    infile.close();//读取文件结束

    int flag,now;
    flag=1;
    now=0;//数组a下标
    while(flag<=n)//m阶数独个数
    {
    int j1,j2;
    for(j1=0;j1<m;j1++)
    for(j2=0;j2<m;j2++)
    {
    Sudoku[j1][j2]=(int)a[now]-48;
    now++;
    }
    outfile<<flag<<":"<<endl;

            SolveSudoku(0,0);
            flag++;
            
            
    }
       
    outfile.close() ; 
    

    return 0;
    }

    ##3.3阶到9阶
     一开始就是用回溯写了九宫格,然后拓展到其他宫格,只是判断所填数字合法性上面加了判断就没什么差别。
    

    bool isValid(int row, int col, int val)//检查填入数字的合法性
    {
    if (row < 0 || row >= m || col < 0 || col >= m)
    {
    return false;
    }

    if (Sudoku[row][col] != 0)
    {
    return false;
    }

    for (int i = 0; i < m; i++)
    {
    if (Sudoku[row][i] == val)
    {
    return false;
    }
    }

    for (int i = 0; i < m; i++)
    {
    if (Sudoku[i][col] == val)
    {
    return false;
    }
    }

    if(m==4)
    {
    int row1 = row / 2;
    int col1 = col / 2;
    int rowstart = row1 * 2;
    int colstart = col1 * 2;
    for (int i = rowstart; i < rowstart + 2; i++)
    {
    for (int j = colstart; j < colstart + 2; j++)
    {
    if (Sudoku[i][j] == val)
    {
    return false;
    }
    }
    }
    }

    if(m==6)
    {
    int row1 = row / 2;
    int col1 = col / 3;
    int rowstart = row1 * 2;
    int colstart = col1 * 3;
    for (int i = rowstart; i < rowstart + 2; i++)
    {
    for (int j = colstart; j < colstart + 3; j++)
    {
    if (Sudoku[i][j] == val)
    {
    return false;
    }
    }
    }
    }

    if(m==8)
    {
    int row1 = row / 4;
    int col1 = col / 2;
    int rowstart = row1 * 4;
    int colstart = col1 * 2;
    for (int i = rowstart; i < rowstart + 4; i++)
    {
    for (int j = colstart; j < colstart + 2; j++)
    {
    if (Sudoku[i][j] == val)
    {
    return false;
    }
    }
    }
    }

    if(m==9)
    {

    int row1 = row / 3;
    int col1 = col / 3;
    int rowstart = row1 * 3;
    int colstart = col1 * 3;
    for (int i = rowstart; i < rowstart + 3; i++)
    {
    for (int j = colstart; j < colstart + 3; j++)
    {
    if (Sudoku[i][j] == val)
    {
    return false;
    }
    }
    }
    }

    return true;

    }

    #性能分析
    ![](https://img2018.cnblogs.com/blog/1797579/201909/1797579-20190925172602399-919655617.png)
    
    ![](https://img2018.cnblogs.com/blog/1797579/201909/1797579-20190925172715970-1661711036.png)
    
    #测试结果
    因为刚开始没有文件读写操作,是直接定义的数独,后来用文件读写操作,变量m忘记设成全局变量,导致SolveSudoku函数出错(用到参数m),然后我以为是自己文件读写操作有错,就开始找bug,从文件输入验证输入有没有错,再验证输出有没有错(这边验证是新建程序操作的),发现并没有错,但在源程序里面就是不行,因为我就写了两个函数,所以就看函数有没有写错才发现参数传递有错(忘记保留错误截图了)。
    ![](https://img2018.cnblogs.com/blog/1797579/201909/1797579-20190925145009833-1465291185.png)
    
    ![](https://img2018.cnblogs.com/blog/1797579/201909/1797579-20190925145016966-925366527.png)
    #心得体会
    怎么说呢,解数独题目感觉不难,很快就写完了(用devc++写的),后来要调试和性能分析不得不去安装vs,安装花了很长时间,安装完还不会用,又琢磨了很久才搞完,最头大的是那个预编译头,第一次碰到,同学也不是很清楚,就又各种试,最后还是在同学帮助下才弄好的。但过程下来还是有很多收获的,会用vs(基本的操作),预编译又是啥,GitHub操作等。最大体会就是和同学交流更容易懂,百度有时候讲的太多又看不懂(我太难了),整个过程下来,总结就是要多动手,多找资料,不懂去问。
  • 相关阅读:
    react-native项目之样式总结
    charles捕获手机端请求数据
    git常用命令常用场景
    window.open新打开窗口与新开标签页
    IE浏览器兼容性模式
    atom编辑器社区插件推荐
    操作linux命令
    java.lang.OutOfMemoryError处理错误
    SQLServer中ISNULL、NULLIF和CONVERT函数
    plsql 查询结果窗口 不正常
  • 原文地址:https://www.cnblogs.com/hurricane1/p/11581445.html
Copyright © 2020-2023  润新知