第二次作业-数独九宫格

第二次作业


1.GitHub项目地址:

  https://github.com/JAZI6/No.2_Homework_Sudoku/tree/master/sudoku

2.解题思路:

  一开始的想法是每行1-9随机产生,然后根据行或列是否产生冲突再进行调整,最后产生合法的九宫格。但是,我接着想却发现,九宫格是行与行且列与列相互影响,动一而触发全体不适,再加上我上网查看的博客,发现我这种想法不好并且很难实现,后来又接着看其他人的博客寻找想法,看见一些做法:暴力深度搜索,回溯等等,发现自己不是很懂,于是又接着寻找,并向大佬同学们讨教了一番,渐渐发现比较适合自己的做法:先随机产生九个数(随机出一个3x3小宫格,或者是9x9大宫格的一行/列),然后对该随机产生的东西进行一些矩阵变换,慢慢衍生出下一个小部分直到最后完成9x9大宫格,那么这种衍生方式就有很多种了,我采取的是先随机生成行,再进一些行/列的变换,所以实际上,看似不同的两个九宫格,可能只是一行或一列上有所差异。

3.设计实现:

  主要是由main函数调用其它的功能函数

  功能函数:StringToNum(string String_Num)//直接将字符串转换为数字的函数,很方便。(独立使用)

       OrderCheck(int arr, string check1, string check2)//对于输入的cmd指令格式进行检查(独立使用)

       CoutToTxt(struct SDK N[], int n)//输出到txt文件里,固定操作,一般都是这样处理(独立使用)

                         TopRowCreate(struct SDK N[], int n)//对九宫格第一行的随机生成(独立使用)

       TransformRow(struct SDK N[], int i);//变换行,然后进行列变换(受到transform的调用)

       transform(struct SDK N[], int n)//行变换(调用TransformRow)

4.关键代码:

  思路:我采取的是先生成固定的第一行(之所以可以这样,是因为后面的变换种类数量可以满足要求,当然,第一行也可以随机产生),再进一些行/列的变换(先变换出前三行,在进行列的变换),所以实际上,看似不同的两个九宫格,可能只是一行或一列上有所差异。

void TopRowCreate(struct SDK N[], int n)//对九宫格第一行的生成
{
    for (int i = 0; i < n; i++)   N[i].SDK_Array[0][0] = (0 + 6) % 9 + 1;
    //我自己的学号:031502206

    for (int i = 0; i < n;)
    {
        int temp[8] = { 9,5,3,4,2,6,8,1 };//设置第一行,这里也可以随机生成。
        int count = 0;

        while(true)
        {

            for (int j = 0; j < 8; j++)   N[i].SDK_Array[0][j + 1] = temp[j];
            i += 6;         //因为3的全排列为6,所以1个可以转换出6个不同的宫格
            count++;
            if (next_permutation(temp, temp + 8) == true && count != n / 6) break;//这里使用了一个库函数,主要用于排列组合
        }
    }


    for (int i = 0; i < n; i += 6)
    {
        for (int j = 1; j < 6; j++)   N[i + j] = N[i];
    }
}
void transform(struct SDK N[], int n)
{
    int temp[3];
    //这里进行变换,之后便出现三个不同的3x3宫格

    for (int i = 0; i < n;)
    {

        for (int j = 0; j < 3; j++)     temp[j] = N[i].SDK_Array[0][j];

        sort(temp, temp + 3);

        while(true)
        {
            N[i].SDK_Array[1][6] = temp[0]; N[i].SDK_Array[1][7] = temp[1]; N[i].SDK_Array[1][8] = temp[2];
            i++;
            if(next_permutation(temp, temp + 3) == true) break;
        }
    }

    for (int i = 0; i < n; i++)
    {
        for (int j = 3, k = 0, m = 0; m < 6; k++, j = (j + 1) % 9, m++)   N[i].SDK_Array[1][k] = N[i].SDK_Array[0][j];
        //进行第二行相关操作
        for (int j = 6, k = 0, m = 0; m < 9; k++, j = (j + 1) % 9, m++)   N[i].SDK_Array[2][k] = N[i].SDK_Array[0][j];
        //进行第三行相关操作
        TransformRow(N, i);//每次衍生出上三行后,通过它们在进行关于列的变换,进而产生完整的宫格
    }
}
void TransformRow(struct SDK N[], int i)//变换行,然后进行列变换
{
    int num = rand() % 2;

    if (num == 1)
    {

        for (int m = 0; m < 3; m++)
        {

            for (int j = m * 3; j < 3 * (m + 1); j++)
            {
                for (int k = 0; k < 3; k++)
                {
                    if (j == 2 || j == 5 || j == 8)   N[i].SDK_Array[k + 3][j - 2] = N[i].SDK_Array[k][j];//对应列变换的核心操作
                    else   N[i].SDK_Array[k + 3][j + 1] = N[i].SDK_Array[k][j];
                }
            }
        }


        for (int m = 0; m < 3; m++)
        {
            for (int j = m * 3; j < 3 * (m + 1); j++)
            {
                for (int k = 0; k < 3; k++)
                {
                    if (j == 0 || j == 3 || j == 6)   N[i].SDK_Array[k + 6][j + 2] = N[i].SDK_Array[k][j];//同上注释
                    else   N[i].SDK_Array[k + 6][j - 1] = N[i].SDK_Array[k][j];
                }
            }
        }
    }

    else
    {
        for (int m = 0; m < 3; m++)
        {
            for (int j = m * 3; j < 3 * (m + 1); j++)
            {
                for (int k = 0; k < 3; k++)
                {
                    if (j == 0 || j == 3 || j == 6)   N[i].SDK_Array[k + 6][j + 2] = N[i].SDK_Array[k][j];//同上注释
                    else    N[i].SDK_Array[k + 6][j - 1] = N[i].SDK_Array[k][j];
                }
            }
        }
        for (int m = 0; m < 3; m++)
        {
            for (int j = m * 3; j < 3 * (m + 1); j++)
            {
                for (int k = 0; k < 3; k++)
                {
                    if (j == 2 || j == 5 || j == 8)    N[i].SDK_Array[k + 3][j - 2] = N[i].SDK_Array[k][j];//同上注释
                    else    N[i].SDK_Array[k + 3][j + 1] = N[i].SDK_Array[k][j];
                }
            }
        }

    }
}

 

 

 5.测试与运行:

   1)非法指令:

    参数个数错误:

      指令格式错误:(后面的乱码和n其实是\n,原来的代码里不加这个就编译错误,我都不知道为什么。)

    N值形式错误:

   2)正确指令:

  测试的结果如下:

6.性能分析:(未完成,软件组件有问题,但还是没解决)

    1)GPU的分析失败:

    2)性能查探失败:

    3)内存查看失败:

7.psp表格:

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

3940


8.对执行力和泛泛而谈的理解:

    执行力我个人认为执行力是指对于自己的计划或者想法的实现,愿意主动具体为它们采取某些行为的能力,执行力其实反映了对于自己计划和想法的实现欲望的强烈程度,所以因事和人而异。

     泛泛而谈的话,应该就是总在讨论与问题事情核心关键无关或者与之关系不大的东西,总是切不到要害。

   

posted @ 2017-09-10 10:54  JAZI6  阅读(396)  评论(1编辑  收藏  举报