软工实践2017第二次作业

解题思路

拿到题目后,心里一凉,怎么还没开学就整这么难的题。。。然后去网上百度、论坛找各种资料,发现还蛮有意思。看了几种解法,发现回溯法好像和大二学的数据结构里的方法有些类似,有点印象。然后看了题目,直觉告诉我用回溯法应该能解。回溯法的基本思想是:从问题的某一种状态(初始状态)出发,搜索从这种状态出发所能达到的所有“状态”,当一条路走到“尽头”的时候(不能再前进),再后退一步或若干步,从另一种可能“状态”出发,继续搜索,直到所有的“路径”(状态)都试探过。这种不断“前进”、不断“回溯”寻找解的方法,就称作“回溯法”。数独这题可以用回溯法。

设计实现

用回溯法实现的流程图如下:

代码说明

1.判断可以放哪些数字

void ConfirmCandidate( int (*a)[9], int i, int j )  
{  
    for( int i_candidate = 0; i_candidate < 9; i_candidate++ )  
        candidate[i_candidate] = i_candidate+1;  
    for( int colm = 0; colm < 9; colm++ )  
    {  
        if( a[i][colm] != 0 )  
            candidate[a[i][colm]-1] = 0;  
    }  
    for( int line = 0; line < 9; line++ )  
    {  
        if( a[line][j] != 0 )  
            candidate[a[line][j]-1] = 0;  
    }  
    for( int line = i/3*3; line < i/3*3+3; line++ )  
    {  
        for( int colm = j/3*3; colm < j/3*3+3; colm++ )  
            if( a[line][colm] != 0 )  
                candidate[a[line][colm]-1] = 0;  
    }  
}  

2.标记每个空格位置

void TotalNumbers( int (*a)[9], int i, int j )  
{  
    for( int line = 0; line < i; line++ )  
    {  
        for( int colm = 0; colm < j; colm++ )  
            if( a[line][colm] == 0 )  
            {  
                g_a[line][colm] = 1;  
            }  
    }  
}  

3.判断所填数字是否正确

bool JudgeValue( int (*a)[9],int i, int j )  
{  
    for( int colm = 0; colm < 9; colm++ )  
    {  
        if( a[i][colm] == a[i][j] && j != colm )  
            return false;  
    }  
    for( int line = i/3*3; line < i/3*3+3; line++ )  
    {  
        for( int colm = j/3*3; colm < j/3*3+3; colm++ )  
            if( a[line][colm] == a[i][j] && i != line && j != colm )  
                return false;  
    }  
    return true;  
}  

4.判断是否成功

bool success( int(*a)[9], int i, int j )  
{  
    if( i < 0 || j < 0 ) return false;  
    int line = i;  
    int colm = j;  
    for( ; line < 9; line++, colm = 0 )  
    {  
        for( ; colm < 9; colm++ )  
        {  
            if( a[line][colm] != 0 && g_a[line][colm] == 0 ) continue;  
            ConfirmCandidate(a, line, colm);  
            for(int c = 0; c < 9; c++ )  
            {  
                if( candidate[c] > a[line][colm] )  
                {  
                    a[line][colm] = candidate[c];  
                
                    for(int i = 0; i < 9; i++ ) 
                        cout << candidate[i] << " "; 
                    cout << endl << endl; 
                    */  
                    //print(a);  
                    bool bRet = JudgeValue( a, line, colm );  
                    if(!bRet)   
                    {  
                        //cout << "bRet  is  false" << endl;  
                    }  
                    else{  
             
                        break;  
                    }  
                }  
                else if( c == 8 && candidate[c] <= a[line][colm] )  
                {  
                    int set_colm = 8;  
                    a[line][colm] = 0;  
                    if( colm == 0 )  
                    {  
                        while( g_a[line-1][set_colm] == 0)  
                        {  
                            if( set_colm == 0)   
                            {  
                                line--;  
                                set_colm = 8;  
                            }  
                            else set_colm--;  
                        }  
                        return success( a, line - 1, set_colm);  
                    }  
                    else{  
                        while( g_a[line][colm-1] == 0)  
                        {  
                            if( colm-1 == 0)   
                            {  
                                line--;  
                                colm = 9;  
                            }  
                            else colm--;  
                        }  
                        return success( a ,line, colm-1 );  
                    }  
                }  
            }  
        }  
    }  
    return true;  
}  

测试运行

性能分析与改进

单元测试还没完成,正在探索中。。。因为开学这几天比较忙,没时间,附加题也来不及做。另外,程序中有bug,有时输出的结果会出现重复的数独棋盘,这几天会不断完善。

PSP表格

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

因为时间确实很紧,也没有尽全力在做,不过这两天会不断完善。O(∩_∩)O

原文地址:https://www.cnblogs.com/dhq409/p/7502065.html