软工实践2017第二次作业

解题思路

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

设计实现

用回溯法实现的流程图如下:
1226935-20170910222207085-745303699.png

代码说明

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;  
}  

测试运行

1226935-20170910214306616-562578129.png

1226935-20170910215344444-1803137530.png

性能分析与改进

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

PSP表格

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

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

转载于:https://www.cnblogs.com/dhq409/p/7502065.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值