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

GitHub地址:https://github.com/weim3731

PSP表格

PSP Personal Software Process Stages 预估耗时(小时) 实际耗时(小时)
Planning 计划 1 1
Estimate 估计这个任务需要多少时间 28 36
Development 开发 6 6
Analysis 需求分析 (包括学习新技术) 0.5 0.5
Design Spec 生成设计文档 0.5 0.5
Development 设计复审 2 2
Coding Standard 代码规范 (为目前的开发制定合适的规范) 1 1
Coding 具体编码 8 16
Code Review 代码复审 3 3
Test 测试(自我测试,修改代码,提交修改) 2 0.5
Reporting 报告 0.5 0.5
Test Report 测试报告 2 1
Size Measurement 计算工作量 0.5 1
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 1 1
Total 合计 28h 34

计算模块接口的设计与实现过程

void clear(int m);
void input(int m);
void output(int m);
int select(int step,int *i,int *j);
void back(int step,int *i,int *j);


代码

1. clear函数

由于存在多个盘面需要求解,故在每次解之前需将程序中原数组进行清零,clear函数便用于执行清零操作。

void clear(int step)            //step为阶数
{
    int i, j;
    for (i = 0; i < step; i++)
        for (j = 0; j < step; j++)
            sd[i][j] = 0;
}

2. input函数

用于从文件输入需要解的盘面。

void input(int step)            //step为阶数
{
    int i, j;
    for (i = 0; i < step; i++)
        for (j = 0; j < step; j++)
            cin >> shudu[i][j];                //从文件输入sd[i][j]
}

3. output函数

用于向文件输出解出的盘面答案。

void output(int step)           //step为阶数
{
    int i, j;
    for (i = 0; i < step; i++)
    {
        for (j = 0; j < step; j++)
        {
            cout << shu[i][j];           //向文件输出盘面,
            if (j < step - 1)
                cout << " ";
        }
        cout << endl;
    }
    cout << endl;
}

4. select函数

判断某位置的可选值

    int select(int *i,int *j)
    {
        num=(*i)*step+(*j);
        l=0;
        // 初始化可选值状态表,并判断是否有可选值 
        for(t=0;t<step;t++)
        {
            if(state[num][t]!=unusable)
            {
                state[num][t]=1;
                l++;
            }
        }
        if(l<1)
            return 0; 
            
        l=0;
        // 若数独中这个格子有值(即数独游戏提供的数字),则可选值就只有一个 
        if(shudu[*i][*j]!=empty)
        {
            for(t=0;t<step;t++)
            {
                state[num][t]=unusable;
            }
            state[num][shudu[*i][*j]-1]=1;
//            l=1; 
        }
        
        // 从横、竖、小九宫格3种约束条件判断可选值 
        for(t=0;t<step;t++)
        {
            if(shu[*i][t]!=empty && t!=*j)
            {
                state[num][shu[*i][t]-1]=unusable;
            }
        }
        for(t=0;t<step;t++)
        {
            if(shu[t][*j]!=empty && t!=*i)
            {
                state[num][shu[t][*j]-1]=unusable;
            }
        }
            
        i0=(*i)-(*i)%3;
        j0=(*j)-(*j)%3; 
        for(s=0;s<3;s++)
        {
            for(t=0;t<3;t++)
            {
                if(shu[s+i0][t+j0]!=empty && (s+i0!=*i || t+j0!=*j))
                {
                    state[num][shu[s+i0][t+j0]-1]=unusable;
                }
            }
        }
        
        // 统计可选值的数量 
        for(t=0;t<step;t++)
        {
            if(state[num][t]!=unusable)
            {
                l++;
            }
        }
        
        return l;
        
    }

5. back函数

追溯上一个位置

    void back(int step,int *i,int *j)
    {
        (*j)--;
        if(*j<0)
        {
            *j=step-1;
            (*i)--;
        }
    } 
    
    // 计算出下一个空格的位置
    void next(int *i,int *j)
    {
        (*j)++;
        if(*j>step-1)
        {
            *j=0;
            (*i)++;
        }
    } 
    
    // 回溯所有空格,找出可行解
    i=0;j=0;
    l=0;
    while(i<step)
    {
        // 判断某位置的可选值
        l=select(&i,&j);
        num=i*step+j;
        times++;

        
        // 若此位置没有可选值,则回溯其上一位置并清空此位置的可选值
        if(l<1)
        {
            for(t=0;t<step;t++)
            {
                state[num][t]=1;
            }
            back(&i,&j);
            // 运算完所有情况后,无解(即第一个各自没有可行解) 
            if(i<0)
            {
                unsolved=0; 
                break; 
            } 
            num--;
            state[num][shu[i][j]-1]=unusable;// 其上一格数字为不可选
            shu[i][j]=shudu[i][j]; // 恢复为初始值 
            
            continue;
        }
        else
        {
            // 选择某一值 
            for(t=0;t<step;t++)
            {
                if(state[num][t]!=unusable)
                {
                    shu[i][j]=t+1;
                    break; 
                } 
            }
            
            // 进行下一位置的运算
            next(&i,&j); 
            
            continue;
        }
    }

总结

我认为这次作业业对我来说很有难度的,都要提交作业了许多事情还没有得到很好的理解。 我最初想用Java来做,但是Java环境是几天前构建的才刚入门。还无法用Java完成这次作业,所以只能用C ++勉强对付。此外,由于我不熟悉PSP表格,做的时候也没有详细的记录。是后面填上去的。还有对GitHub也不熟悉,在完成工作的过程中学会很多了,但还有有些人到目前为止还没有学到(作业截止后仍会继续学习)。 总而言之,通过这次作业,我深刻理解了软件工程实践与以前的代码类之间的区别。 接下来的第一次结队编程作业,为了不拖累队友的后腿,我将尽力跟上队友的节奏,并利用自己的空闲时间改善自己,学习新知识。

posted on 2019-09-25 21:35  FZU_阿木_031702448  阅读(210)  评论(1编辑  收藏  举报