Soft Engineering Practice 2019 third operation

Flexible work practices third operation

0.Github address

https://github.com/muke2000/031702418

1.PSP table

Personal Software Process Stages Estimated time consuming (minutes) The actual time-consuming (minutes)
plan 30 20
Estimate how much time this task requires 10 10
Develop 200 150
Needs analysis (including learning new technologies) 60 40
Generate design documents 60 60
Design Review 30 20
Code specifications (development of appropriate norms for the current development) 10 10
Specific design 40 30
Specific coding 120 180
Code Review 30 20
Test (self-test, modify the code, submit modifications) 400 180
report 60 30
testing report 60 40
Computing workload 30 15
Later summarized, and process improvement plan 60 40
total 1300 845

2. Problem-solving ideas

看到题目为解数独,且最大宫数为9时我便决定用深度优先搜索直接搜索出解。

3. Design Process

由于本题只是一道算法题,于是我便决定只设计一个类来求解,该类主要由main函数、输入输出函数、判断函数、深度优先搜索函数组成。

3.0 input and output functions

Reads the parameters n, m is determined to enter a few disk, the disk is directly input to each call stops and only the output function Solution

public static void inAndOut(int n,String in,String out,int m) throws IOException {
        File input = new File(in);
        File output = new File(out);
        BufferedReader reader = null;
        BufferedWriter writer = null;
        reader = new BufferedReader(new FileReader(input));
        writer = new BufferedWriter(new FileWriter(output));
        for(int l=0;l<n;l++){//l表示当前读到第几盘
            for(int i=0;i<m;i++){
                String s = reader.readLine();//读入该行
                String str = s.replace(" ","");//删除空格
                for(int j=0;j<m;j++){
                    char [] chars = str.toCharArray();//char转为int
                    array[i][j] = chars[j]-48;
                }
            }
            if(dfs(0,m)){
                for(int i=0;i<m;i++){
                    for(int j=0;j<m;j++){
                        writer.write(array[i][j]+" ");
                    }
                    writer.newLine();//写入新的一行
                }
            }else {
                writer.write("no result");
            }
            writer.newLine();
            String s = reader.readLine();
        }
        writer.close();
    }

3.1 judging function

Depending on the position you want to fill in the spaces, the number is about to fill the ranks of digital compared with the corresponding empty and the house, if the same can not be filled in the blank

private static boolean isIn(int n,int x,int y,int m){
        for(int i=0;i<m;i++){
            if(array[x][i]==n||array[i][y]==n)//判断与该行该列的数字是否相同
                return false;
        }
        if(m==9) {//宫数为9时判断与该宫内的数字是否相同
            for (int i = (x / 3) * 3; i < (x / 3 + 1) * 3; i++) {
                for (int j = (y / 3) * 3; j < (y / 3 + 1) * 3; j++) {
                    if (array[i][j] == n)
                        return false;
                }
            }
        }
        if (m==4){//宫数为4时判断与该宫内的数字是否相同
            for (int i = (x / 2) * 2; i < (x / 2 + 1) * 2; i++) {
                for (int j = (y / 2) * 2; j < (y / 2 + 1) * 2; j++) {
                    if (array[i][j] == n)
                        return false;
                }
            }
        }
        if(m==6) {//宫数为6时判断与该宫内的数字是否相同
            for (int i = (x / 2) * 2; i < (x / 2 + 1) * 2; i++) {
                for (int j = (y / 3) * 3; j < (y / 3 + 1) * 3; j++) {
                    if (array[i][j] == n)
                        return false;
                }
            }
        }
        if(m==8) {//宫数为8时判断与该宫内的数字是否相同
            for (int i = (x / 4) * 4; i < (x / 4 + 1) * 4; i++) {
                for (int j = (y / 2) * 2; j < (y / 2 + 1) * 2; j++) {
                    if (array[i][j] == n)
                        return false;
                }
            }
        }
        return true;
    }

3.2 depth-first search function

Sequentially from the first row of the first column of the space to start the search, such as a digital spaces to skip the empty or inspection from 1 to 9 with a test function sequence, such as not met, the process returns to on an empty, fill 81 empty until the end of recursion. I started to write the function definition is void dfs function type, as follows

public static void dfs(int x,int m){
        if (x == (m*m)) {//如果以填完最后一空返回
            return;
        }
        int i = x / m;
        int j = x % m;
        if (array[i][j] == 0) {
            for (int k = 1; k <= m; k++) {
                if (isIn(n,i,j,m) {//该数字没有重复,可以填入
                    array[i][j] = k;
                    dfs(x + 1,m);//继续填下一空
                }
                array[i][j] = 0;//清除掉刚填过的数字,将盘面退回原样
            }
        } else {
            dfs(x + 1,m);//继续填下一空
        }
    }

This code runs after the output file with exactly the same as the input file, then I see other people's code on the blog found a logical and, like me, but the result put output in the depth-first search reaches the last space, you can get the right result, code differences as above

public static void dfs(int k,int m,String outputFilename) throws IOException {
        if (k == (m*m)) {
            try{//直接将结果输出
                File output = new File(outputFilename);
                BufferedWriter writer = null;
                writer = new BufferedWriter(new FileWriter(output));
                for(int i=0;i<m;i++){
                    for(int j=0;j<m;j++){
                        writer.write(table[i][j]+" ");
                    }
                    writer.newLine();
                }
                writer.newLine();
                writer.close();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            return;
        }
        int x = k / m;
        int y = k % m;
        if (table[x][y] == 0) {
            for (int i = 1; i <= m; i++) {
                table[x][y] = i;
                if (judge(table,x, y, i,m)) {
                    dfs(k + 1,m,outputFilename);
                }
            }
            table[x][y] = 0;
        } else {
            dfs(k + 1,m,outputFilename);
        }
    }

So I suspect that is because there is no timely output, after reaching 81 empty, recursive functions and has retreated back to the previous state, resulting in ready-packed space is eliminated, so I added an array to store the disk to prevent the completed air is emptied, as follows

    public static int [][] res = new int[9][9];
    public static void dfs(int num,int m)
    {
        if(num==m*m){//将数组保存到另一个新数组,并返回
            for(int i=0; i<m; i++){
                for(int j=0; j<m; j++)
                    res[i][j]=array[i][j];
            }
            return ;
        }
        int i=num/m,j=num%m;
        if(array[i][j]!=0) dfs(num+1,m);
        else{
            for(int k=1; k<=m; k++)
            {
                if(isIn(k,i,j,m))
                {
                    array[i][j]=k;
                    dfs(num+1,m);
                }
            }
            array[i][j]=0;
        }
        return ;
    }

This time has been correctly solved Sudoku, but when I tested, I found that if the number of unique solutions for multiple solutions and the number is larger, the code needs to run a very long time to results, because the function will always been traversed all cases will be the outcome, and require large memory space, so I took the dfs function into form in reaching the first solution can be directly returned the following code

public static boolean dfs(int x,int m){
        int i,j;
        i = x/m;j = x%m;
        if(x==m*m){//如过已填完最后一空则返回true
            return true;
        }
        if(array[i][j]!=0) return dfs(x+1,m);//继续填下一空
        for(int n=1;n<=m;n++){
            if(isIn(n,i,j,m)){
                array[i][j] = n;
                if(dfs(x+1,m)) return true;//如果下一空结果正确则返回true;
                array[i][j] = 0;//如果下一空没有可以填入的数字则应清除该空以填入的数据,填入下一个可用数字
            }
        }
        return false;//该空找不到可以填入的数字,返回false以返回到上一空
    }

The function returns a value according to the state before the return value to determine whether to return, then the result can be output can be set to boolean the first time reached the last empty.

4 Ways to Improve

The main ideas are to reflect on the upper part of the 3.2 depth-first search function.

The test design unit

My test unit is divided into three steps
The first step is to input and output section of the test;
the second step is to test the number of parts alone to solve, because of the c ++ more familiar, I started to realize With c ++ algorithm used, only after transplantation java;
the third step is to integrate the previous two parts of the complete code for testing.

6. mentality and harvest

The operation is relatively simple, the main difficulty for me is the depth-first search function design, this assignment deepened my understanding of the depth-first search and recursive, but how to build software and not very helpful.

Guess you like

Origin www.cnblogs.com/muke2000/p/11581778.html