#软件工程第三次作业

软件工程第三次作业之数独

列表项

标签(空格分隔): 未分类


Github项目地址:https://github.com/jjsgxty/031702510

PSP表格

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

解题过程

刚开始看到作业的时候,想到可以用DFS递归来实现,作业要求是3~9宫格的实现,我想先完成九宫格的话,其他宫格再改一改就可以了,然后我就开始了九宫格的代码。
1.用深搜构造数独,分别判断每个格子中填入的数字是否正确,如果当前格子不为空就跳过
2.判断填入的数是否正确时,先判断横列,再判断纵列,最后判断每个小宫格
3.全部都符合后,退出递归

完成了九宫格的实现后,我发现麻烦的是cmd命令行参数,刚开始真的很懵,命令行参数不会,文件流也不懂,看了c++书中有关文件流输入输出的内容后会使用文件流,但cmd行参数百度了一堆还是不理解什么意思,最后求助了一位同学,才终于大致搞明白

然后就是进行其他宫格的补充,3、5、7宫格比较简单,只需要判断每一行每一列,所以我把4、6、8、9放在了一起,从九宫格到所有宫格的过程中我经常会在一些细节性的地方忘记修改,每次找都找的很烦,还有我在检验一个宫格是否正确输出的时候,会把输入文件错放成其他宫格的输入文件,找了半天错误原来是文件问题。唉,还是希望自己以后能细心一些吧┭┮﹏┭┮

Check 函数

   //判断shu填入n时是否满足条件

bool Check(int n, int shu)
{
    //判断n所在横列是否合法 
    for (int i = 0; i < siz; i++)
    {
        int j = n / siz;    // j为n竖坐标
        if (num[j][i] == shu) return false;
    }

    //判断n所在竖列是否合法 
    for (int i = 0; i < siz; i++)
    {
        int j = n % siz;    //j为n横坐标 
        if (num[i][j] == shu) return false;
    }
    if (siz == 4 || siz == 6 || siz == 8 || siz == 9)
    {
        int a, b;   //a为每个小宫格中横向的格子数,b为纵向格子数 
        switch (siz)
        {
        case 4:
            a = 2, b = 2;
            break;
        case 6:
            a = 3, b = 2;
            break;
        case 8:
            a = 2, b = 4;
            break;
        case 9:
            a = 3, b = 3;
            break;
        }
        int x = n / siz / b * b;     //x为n所在的小宫格左顶点竖坐标

        int y = n % siz / a * a;     //y为n所在的小宫格左顶点横坐标


        //判断n所在的小宫格是否合法 
        for (int i = x; i < x + b; i++)
        {
            for (int j = y; j < y + a; j++)
            {
                if (num[i][j] == shu) return false;
            }
        }
    }
    return true;    //都合法,返回正确

}

DFS函数

//深搜构造数独 
int DFS(int n)
{
    int amount = 0;
    switch (siz)
    {
    case 3:
        amount = 8;
        break;
    case 4:
        amount = 15;
        break;
    case 5:
        amount = 24;
        break;
    case 6:
        amount = 35;
        break;
    case 7:
        amount = 48;
        break;
    case 8:
        amount = 63;
        break;
    case 9:
        amount = 80;
        break;
    }
    //所有的都符合,退出递归 

    if (n > amount)
    {
        sign = true;
        return 0;
    }

    //当前位不为空时跳过
    if (num[n / siz][n % siz] != 0)
    {
        DFS(n + 1);
    }

    else
    {
        //否则对当前位进行枚举测试 
        for (int i = 1; i <= siz; i++)
        {
            //满足条件时填入数字 
            if (Check(n, i) == true)
            {
                num[n / siz][n % siz] = i;
                DFS(n + 1);    // 继续搜索 

                 //返回时如果构造成功,则直接退出 
                if (sign == true) {
                    return 0;
                }

                //如果构造不成功,还原当前位 
                    num[n / siz][n % siz] = 0;
            }

        }

    }
    return 0;  //此处不加会有警告
}

主函数

int main(int argc, char* argv[])
{
    int k;
    char* in;  //输入文件 
    char* out;  //输出文件 
    int time;   //盘面数目 
    
    siz = atoi(argv[2]);  //atoi (ascii to integer)是把字符串转换成整形数的一个函数 
                       //头文件为 #include <stdlib.h> 
    time = atoi(argv[4]);
    
    in = argv[6];
    ifstream infile(in);
    out = argv[8];
    ofstream outfile(out);
    
    for (k = 0; k < time; k++) {
        char temp[10][10] = { 0 };
        int l = 0;
        for (int i = siz * k + k; i < siz * k + k + siz; i++)
        {
            for (int j = 0; j < siz; j++)
            {
                infile >> temp[i][j];
                num[l][j] = temp[i][j] - '0';   // 两个字符相减就是ASCII码之间的减法操作
            }

            l++;
        }
        cout << "\n";
        sign = false;    //此处注意一定要加!!!
        DFS(0);

        for (int i = 0; i < siz; i++)
        {
            for (int j = 0; j < siz; j++)
            {
                cout << num[i][j] << " ";
            }
            cout << "\n";
        }
        cout << "\n";  

        ofstream outfile;
        outfile.open("output.txt", ios::app);   //以后继方式打开文件以便继续写
        for (int i = 0; i < siz; i++) {
            for (int j = 0; j < siz; j++) {
                outfile << num[i][j] << " ";
            }
            outfile << endl;
        }
        outfile << "\n";
        outfile.close();
    }
}

测试结果

猜你喜欢

转载自www.cnblogs.com/jjsgxty/p/11588139.html