且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

8皇后解决方案Java代码的说明.

更新时间:2023-11-20 15:20:58

让我们尝试逐步理解代码.首先,我们调用函数solution(),这导致执行谜题答案.

溶液功能:

  public void solution(){整数y = 0;b [0] = -1;而(y> = 0){做 {b [y] ++;//如果最后一个单元格不安全,或者我们到达了棋盘的末端,则进入下一行.} while(((b [y]< 8)&& unsafe(y));;//检查是否是最后一个单元格,以及它是否是不安全的单元格(发生冲突)if(b [y]< 8){//我们找到了一个安全的单元格.万岁!if(y< 7){//我们放置了最后一个女王吗?b [++ y] = -1;//不,让我们分配下一个.} 别的 {putboard();//是的,让我们打印结果!}} else {//如果未找到单个安全单元,我们将重新分配最后一个女王.y--;}}} 

第一次,您将遍历行(或列,但是您更喜欢它.这只是轮换问题)中的每个单元格.在每个单元格上进行不安全(y)检查,以防万一您放置女王的单元格与其他被女王占据的单元格发生冲突(如您已经在注释中找到的那样).>

下一步,一旦我们找到了放置实际皇后(y)的安全单元格,我们就会进行安全检查:如果我们没有找到该皇后区的单个安全单元格,则必须重新分配最后一个皇后区

如果找到该单元格并且该单元格正确,我们将检查它是否为最后一个女王(y

不安全功能:

 公共静态布尔不安全(int y){int x = b [y];//让我们将实际单元格称为"x"for(int i = 1; i< = y; i ++){//对于放置在实际皇后之前的每个皇后,我们必须检查它是否在同一行,列或对角线中.int t = b [y-i];如果(t == x || t == x-i || t == x + i){返回true;//哦,哦,冲突!}}返回false;//是的,没有冲突!} 

此函数检查我们使用的皇后是否与该皇后之前分配的任何皇后发生冲突.冲突可能会在对角线,垂直或水平方向发生:这就是为什么在返回真"语句之前进行三次或"检查的原因.

面板功能:

  public static void putboard(){System.out.println("\ n \ n解决方案" +(++ s));for(int y = 0; y< 8; y ++){for(int x = 0; x< 8; x ++){如果(b [y] == x)System.out.print("| Q");别的System.out.print("| _");}System.out.println("|");}} 

我将不深入解释这一功能,因为它只是一个相当简单的行打印功能,您可以在执行解决方案时自行了解它的工作原理!

希望这会有所帮助.

干杯!

I found a 8-Queen solution that I was able to compile and run in Eclipse. I believe this solution follows the backtracking approach and meat of the work is done in the solution and unsafe functions, but I am having a hard time understanding the code paths in there. Can someone please help me understand what this code is doing.

My Source - http://rosettacode.org/wiki/N-queens_problem#Java I verified the output against the 92 solutions published on other sources. Looks good. So I know the code works.

I have tried to format it and add some basic notes to clear things up -

private static int[] b = new int[8];
private static int s = 0;

public static void main(String[] args) {
    // solution from - http://rosettacode.org/wiki/N-queens_problem#Java
    new QueenN();
}

public QueenN() {
    solution();
}

public void solution() {
    int y = 0;
    b[0] = -1;
    while (y >= 0) {
        do {
            b[y]++;
        } while ((b[y] < 8) && unsafe(y));

        if (b[y] < 8) {

            if (y < 7) {
                b[++y] = -1;
            } else {
                putboard();
            }

        } else {
            y--;
        }
    }
}

// check if queen placement ***es with other queens
public static boolean unsafe(int y) {
    int x = b[y];
    for (int i = 1; i <= y; i++) {
        int t = b[y - i];
        if (t == x || t == x - i || t == x + i) {
            return true;
        }
    }
    return false;
}

// printing solution
public static void putboard() {
    System.out.println("\n\nSolution " + (++s));
    for (int y = 0; y < 8; y++) {
        for (int x = 0; x < 8; x++) {
            if (b[y] == x)
                System.out.print("|Q");
            else
                System.out.print("|_");
        }
        System.out.println("|");
    }
}

End.

Let's try to understand the code step by step. First of all, we call the function solution(), which is what leads to the execution of the puzzle answer.

Solution funcion:

public void solution() {
    int y = 0;
    b[0] = -1;
    while (y >= 0) {
        do {
            b[y]++; //if last cell was unsafe or we reached the end of the board, we go for the next row.
        } while ((b[y] < 8) && unsafe(y)); //Checks whether it's the last cell and if it's an unsafe cell (***ing)

        if (b[y] < 8) { //We found a safe cell. Hooray!

            if (y < 7) { //Did we place the last queen?
                b[++y] = -1; //Nope, let's allocate the next one.
            } else {
                putboard(); //Yup, let's print the result!
            }

        } else { //If not a single safe cell was found, we reallocate the last queen.
            y--;
        }
    }
}

On the first while, you're going to iterate through each cell in a row (or column, however you prefer it. It's just a rotation matter). On each cell you make the unsafe(y) check, which will return true in case the cell you're placing the queen in is ***ing with other queen-occupied cells (as you've already found out in the comment).

Next step, once we've found a safe cell in which to place the actual queen (y), we make a security check: if we have not found a single safe cell for that queen, we have to reallocate last queen.

In case the cell was found and was correct, we check whether it was the last queen (y < 7). If it is so, we proceed to print the result. Otherwise, we just re-start the while loop by placing b[++y] = -1.

Unsafe function:

public static boolean unsafe(int y) {
    int x = b[y]; //Let's call the actual cell "x"
    for (int i = 1; i <= y; i++) { //For each queen before placed BEFORE the actual one, we gotta check if it's in the same row, column or diagonal.
        int t = b[y - i];
        if (t == x || t == x - i || t == x + i) {
            return true; //Uh oh, ***!
        }
    }
    return false; //Yay, no ***es!
}

This function checks whether the queen we're using ***es with any of the allocated queens before this one. The ***es might happen diagonally, vertically or horizontally: That is why there is a triple OR check before the "return true" statement.

Putboard function:

public static void putboard() {
    System.out.println("\n\nSolution " + (++s));
    for (int y = 0; y < 8; y++) {
        for (int x = 0; x < 8; x++) {
            if (b[y] == x)
                System.out.print("|Q");
            else
                System.out.print("|_");
        }
        System.out.println("|");
    }
}

I'm not gonna explain this one that deep, because it is simply a fairly simply line printing function which you can find out how it works by yourself when executing the solution!

Hope this helps.

Cheers!