2019 software engineering practices - the third job

GitHub address

https://github.com/wujunjie1008/031702537

P2P Form

PSP2.1 Personal Software Process Stages Estimated time consuming (minutes) The actual time-consuming (minutes)
Planning plan 30min 15min
Estimate Estimate how much time this task requires 24 hours 26h
Development Develop 5h 2h
Analysis Needs analysis (including learning new technologies) 2h 2h
Design Spec Generate design documents 15min 30min
Design Review Design Review 1h 30min
Coding Standard Code specifications (development of appropriate norms for the current development) 10min 15min
Design Specific design 1h 2h
Coding Specific coding 4h 6h
Code Review Code Review 2h 4h
Test Test (self-test, modify the code, submit modifications) 3h 4h
Reporting report 3h 3h
test repor testing report 30min 1h
Size Measurement Computing workload 15min 15min
Postmortem & Process Improvement Plan Later summarized, and process improvement plan 30min 15min
total 23.16h 26h

demand

The realization of a multi-stage Sudoku solving tool.

Sudoku

Sudoku is a disk nine palaces, each palace is divided into nine small cell. Given certain conditions known digital and solving this eighty-one grid, using logic and reasoning, enter the number 1-9 on the other spaces. 1-9 so that each number appears only once in each row, each column and each palace, also known as "squares."

The initial preparation - Preparation may quicken the work

Due to the requirements of this code is passed to cmd command parameter input and output file formats and needs, so I went to Baidu, did not think the way to solve any doubt I have been before

int main(int   argc, char*   argv[])

The original main () function in the first parameter argc cmd command is applied to the input number of parameters, and the second parameter the argv [] is the string corresponding to the parameters of
the reference after the predetermined input cmd, I wrote the code to import parameters

    char* i;
    char* o;
    int m, n, h, l;

    m = atoi(argv[2]);
    n = atoi(argv[4]);
    i = argv[6];
    ifstream fin(i);
    if (!fin.is_open())
    {
        cout << "输入文件不存在";
        return 0;
    }
    o = argv[8];
    ofstream fout(o);

File Input:

        h = 0;
        while (!fin.eof()) {            //文件输入
            getline(fin, list);
            if (list.length() != 2 * m && list.length() != 2 * m - 1) {     //表格输入不规范,与阶数m不相符则退出
                cout << "表格大小不符合";
                return 0;
            }
            for (l = 0; l < m; l++) {
                num_list[h][l] = list[l * 2] - 48;
                if (num_list[h][l] < 0 || num_list[h][l]>9) {       //表格输入不规范,出现非数字字符则退出
                    cout << "九宫格中出现不是0-9的数字";
                    return 0;
                }
            }
            h++;

File output:

        for (h = 0; h < m; h++) {           //文件输出
            for (l = 0; l < m; l++) {
                fout << num_list[h][l];
                if (l != m - 1)
                    fout << ' ';
                else
                    fout << '\n';
            }
        }
        fout << '\n';

Problem-solving ideas - Mountain darkly

For me personally, if I do Sudoku, I prefer to use more than the only method, and to infer that the spaces through which the same row of the grid, in the same column, the same house number can fill in what numbers, and for difficulty Sudoku is low, there will be a space can only fill a number, when this number is filled in, there will be another one number can only fill the grid, so I think it can be applied to low there are 9 low order of difficulty Palace in the number of cells alone. Specific code as follows:

int weiyu(int m) {
    cout << "使用唯余法" << endl;
    int h, l;
    int may_count;
    int count = 0;
    for (h = 0; h < m; h++) {
        for (l = 0; l < m; l++) {
            if (num_list[h][l] == 0)
                count++;
        }
    }
    for (h = 0; h < m; h++) {
        for (l = 0; l < m; l++) {
            if (num_list[h][l] == 0) {
                int may_num[10] = { 0 };
                may_count = m;
                for (int bh = 0; bh < m; bh++) {        //遍历行
                    if (num_list[bh][l] != 0) {
                        if (may_num[num_list[bh][l]] == 0)
                            may_count--;
                        may_num[num_list[bh][l]] = 1;
                    }
                }
                for (int bl = 0; bl < m; bl++) {        //遍历列
                    if (num_list[h][bl] != 0) {
                        if (may_num[num_list[h][bl]] == 0)
                            may_count--;
                        may_num[num_list[h][bl]] = 1;
                    }
                }
                if (m == 4 || m == 6 || m == 8 || m == 9) {             //遍历宫格
                    int max_h = 0, max_l = 0;
                    int gong_h = 0, gong_l = 0;

                    //定位当前格在属于第几宫格
                    if (m == 4 || m == 8 || m == 9) {
                        gong_l = (int)sqrt(m);
                        gong_h = (int)(m / gong_l);
                    }
                    else if (m == 6) {
                        gong_h = (int)sqrt(m);
                        gong_l = (int)(m / gong_h);
                    }
                    for (int i = 1; i < m; i++) {
                        max_h = i * gong_h;
                        if (max_h > h) {
                            break;
                        }
                    }
                    for (int i = 1; i < m; i++) {
                        max_l = i * gong_l;
                        if (max_l > l) {
                            break;
                        }
                    }

                    //开始遍历
                    for (int i = max_h - gong_h; i < max_h; i++) {
                        for (int j = max_l - gong_l; j < max_l; j++) {
                            if (i > 9)      //消除vs编译器的警告,删去不影响代码
                                i = 9;
                            if (i < 0)
                                i = 0;
                            if (j > 9)
                                j = 9;
                            if (j < 0)
                                j = 0;
                            if (num_list[i][j] != 0) {
                                if (may_num[num_list[i][j]] == 0)
                                    may_count--;
                                may_num[num_list[i][j]] = 1;
                            }
                        }

                    }
                }
                if (may_count == 1) {                   //填写数字
                    for (int i = 1; i <= m; i++) {
                        if (may_num[i] == 0) {
                            num_list[h][l] = i;
                            h = 0;
                            l = -1;
                            count--;                //填写成功,未填数减一
                            if (count == 0) {
                                printf("成功\n");
                                return 0;       //完成数独,返回0
                            }
                            break;
                        }
                    }
                }
            }
        }
    }
    return 1;       //未完成数独,返回1
}

I thought I had done but because after you enter a higher degree of difficulty of the sudoku puzzle, and I feel they fall to the bottom. (Attach original title)
0 0. 8 0. 9 0 0 0 0
0. 7 0 0 0 0 2. 8 0
0. 6. 4. 1 0 0. 3 0. 9
0 0 0. 8 0. 5. 9 0 0
. 5 0 0 0 0 0 0 0. 1
0 0. 9. 3 0. 4 0 0 0
. 8 0 2 0 0. 7. 5. 6 0
0. 9. 7 0 0 0 0. 1 0
0 0 0 0. 6 0. 7 0 0
CD-I method can be used, but once the solution is not unique, or no grid is filled only when the number of Wei Yu law can not solve the answer. Just make a simple Sudoku, salted fish and that there is no difference, so I began looking for new ways.

Problem-solving ideas - vista

Autistic think the main theme of the new method is time, my mind can not think of a grid is a grid tried to go. Later overheard around people are talking DFS (depth-first algorithm), I was very confused, DFS and several unique matter. DFS and then later found it not to have tried every possible thing in the past. But I am running time of DFS still has a hint of worry. Try holding the attitude, I started writing the DFS function.
- First, check the function, I am the only change in the original law more than on, in the check () function must appear:

int check(int h, int l, int m) {
    int num[10] = { 0 };
    for (int bh = 0; bh < m; bh++) {        //遍历行,寻找重复的数字
        if (num_list[bh][l] != 0) {
            num[num_list[bh][l]]++;
            if (num[num_list[bh][l]] > 1)
                return 0;
        }
    }
    for (int i = 0; i < 10; i++) {
        num[i] = 0;
    }
    for (int bl = 0; bl < m; bl++) {        //遍历列,寻找重复的数字
        if (num_list[h][bl] != 0) {
            num[num_list[h][bl]]++;
            if (num[num_list[h][bl]] > 1)
                return 0;
        }
    }
    for (int i = 0; i < 10; i++) {
        num[i] = 0;
    }
    if (m == 4 || m == 8 || m == 9 || m == 6) {         //检验九宫格,寻找重复的数字
        
        //定位该单元格所属的宫格
        int max_h = 0, max_l = 0;                   
        int gong_h = 0, gong_l = 0;
        if (m == 4 || m == 8 || m == 9) {
            gong_l = (int)sqrt(m);
            gong_h = (int)(m / gong_l);
        }
        else if (m == 6) {
            gong_h = (int)sqrt(m);
            gong_l = (int)(m / gong_h);
        }
        for (int i = 1; i < m; i++) {
            max_h = i * gong_h;
            if (max_h > h) {
                break;
            }
        }
        for (int i = 1; i < m; i++) {
            max_l = i * gong_l;
            if (max_l > l) {
                break;
            }
        }
        
        //正式开始遍历
        for (int i = max_h - gong_h; i < max_h; i++) {
            for (int j = max_l - gong_l; j < max_l; j++) {
                if (num_list[i][j] != 0) {
                    num[num_list[i][j]]++;
                    if (num[num_list[i][j]] > 1)
                        return 0;       //有重复,返回0
                }
            }
        }
    }

    return 1;       //无重复,返回1
}

- then is our protagonist DFS (depth-first search) function:

int DFS(int n, int m){
    if (n > (m*m)) {
        return 1;
    }
    if (num_list[n / m][n % m] != 0){       // 不需要填数字,则跳过
        if (DFS(n + 1, m) == 1)
            return 1;
    }
    else{
        for (int i = 1; i <= m; i++){       //试填1-9的数字 
            num_list[n / m][n % m] = i;
            if (check(n / m, n % m, m) == 1){
                if (DFS(n + 1, m) == 1)
                    return 1;               //返回时如果构造成功,则返回1
                else
                    num_list[n / m][n % m] = 0;
            }
            else
                num_list[n / m][n % m] = 0;
        }
    }
    return 0;
}

I did not expect after seemingly complex ideas in such a short code can be implemented, the final result is successful, the number of higher difficulty was I alone have won.
. 3. 5. 8. 7. 9 2. 1. 4. 6
. 9. 7. 1. 4. 3. 6 2. 8. 5
2. 6. 4. 1. 5. 8. 3. 7. 9
. 7 2. 6. 8. 1. 5. 9. 3. 4
. 5. 4. 3. 6. 7. 9. 8 2. 1
. 1. 8. 9. 3 2 . 4. 5. 6. 7
. 8. 9. 1 2. 4. 5. 6. 7. 3
. 6. 8. 9. 7. 5. 4. 3. 1 2
. 4. 3. 1. 5 2. 6. 7. 8. 9

Seeking to improve

Partly out of DFS operating speed is not assured, on the other hand I do not want to write before I the only law on this function was deleted, I began probing compare their runtime performance comes with vs Profiler:

- First, It is a function of time alone DFS of:

- followed by more than the only method to use if no solution then use the DFS function of time:

we can see the problem even though the test, only three questions must need to use DFS, but using CD It fajitas DFS strategy to significantly faster than simply using dfs, thus demonstrating Wei Yu law and DFS in conjunction with more efficient over time.

unit test

Step 3:

4 Order:

5 order:

6 Order:

7 Order:

8 Order:

9 order:



to sum up

Through this practice work, I learned for their own projects, not only do it, but also for its debug, do several tests, and optimization, as I finally introduced the DFS algorithm is the same, but I also learned to make detection of the sections of the code with the performance of VS2017 profiler to optimize my code. Not only that, I also learned to be a reasonable allocation of my time, I was at a distance of 4 days when the deadline began to do, do it like a race against time, so there are many places to do deficiencies, after the this job still needs attention.

Guess you like

Origin www.cnblogs.com/J-J-1008/p/11586587.html