1

Java の if-else ステートメントで奇妙な問題が発生しています。以下は、getPathThroughMaze と呼ばれる迷路の終わりを見つけようとする再帰的メソッドです。

private static String getPathThroughMaze(char[][] maze, Set<Point> visited, Point currentPoint) {
    int currentX = currentPoint.x;
    int currentY = currentPoint.y;
    visited.add(currentPoint);

    //end case. append '!' so we know which path leads to the end of the maze
    if (currentX == (xLength - 2) && currentY == (yLength - 1)) {
        return "!";
    }

    char left = maze[currentY][currentX - 1];
    char right = maze[currentY][currentX + 1];
    char up = maze[currentY - 1][currentX];
    char down = maze[currentY + 1][currentX];
    char current = maze[currentY][currentX];

    /* If valid, visit all non-visited adjacent squares.
       Only odd numbered columns will be traversed
       since even numbered columns represent vertical wall
       columns
     */
    if (right == '_' || right == ' ') {
        Point nextPoint = new Point(currentX + 2, currentY);
        if (!visited.contains(nextPoint)) {
            String path = "E" + getPathThroughMaze(maze, visited, nextPoint);
            if (path.endsWith("!")) {
                return path;
            } else {
                //do nothing.
            }
        }else {
            //do nothing.
        }
    } else if (up == ' ') {
        Point nextPoint = new Point(currentX, currentY - 1);
        if (!visited.contains(nextPoint)) {
            String path = "N" + getPathThroughMaze(maze, visited, nextPoint);
            if (path.endsWith("!")) {
                return path;
            } else {
                //do nothing.
            }
        } else {
            //do nothing.
        }
    } else if ( current == ' ' && (down == '_' || down == ' ')) {
        Point nextPoint = new Point(currentX, currentY + 1);
        if (!visited.contains(nextPoint)) {
            String path = "S" + getPathThroughMaze(maze, visited, nextPoint);
            if (path.endsWith("!")) {
                return path;
            } else {
                //do nothing.
            }
        } else {
            //do nothing.
        }
    } else if (left == '_' || left == ' ') {
        Point nextPoint = new Point(currentX - 2, currentY);
        if (!visited.contains(nextPoint)) {
            String path = "W" + getPathThroughMaze(maze, visited, nextPoint);
            if (path.endsWith("!")) {
                return path;
            } else {
                //do nothing.
            }
        } else {
            //do nothing.
        }
    } else {
      return "";  
    }
    //otherwise...
    return "";
}

問題に遭遇した再帰の時点で、変数は次のとおりです。

currentX = 3
currentY = 2
right = '|'
left = '|'
up = ' '
down = '_'
current = ' '
visited contains points (1,1), (3,1), (3,2)

最初の else if ステートメントで:

else if (up == ' ')

訪問済みセットに既に含まれている新しいポイント (3,1) が作成されます。私が期待することは、

if(!visited.contains(nextPoint))

false と評価され、(おそらく、デバッガーで数回クリックした後) に到達します。

else if ( current == ' ' && (down == '_' || down == ' ')) 

ここで、その条件を確認し (これは真であると予想します)、迷路を進み続けることができます。実際に起こることは、私がステップオーバーをクリックしたときです

if(!visited.contains(nextPoint))

デバッガー (elcipse と intellij の両方) は、メソッドの最後の return ステートメントまでずっと移動し、"" を返したいと考えています。他のすべての if else ステートメントがスキップされている理由がわかりません。なぜそうなるのか、誰か教えてもらえますか?私の説明が十分に明確でない場合はお知らせください。

4

1 に答える 1

2

If/elseelse if ( current == ' ' && (down == '_' || down == ' '))ステートメントは排他的であるため、すでにelse if (up == ' ')ブランチに入っているため、に到着することはありません。if(!visited.contains(nextPoint))内部が false であるためif、プログラムはコメントをelse付けてその部分に入り、//do nothing何もしません (実際には、空のステートメントを記述する必要はありませんし、記述するべきではありませんelse。デバッグを容易にするために、少なくともログ ステートメントをそれに追加します。 )。次に、if/elseブロックを出て に進みreturnます。

コードですべてのメソッド呼び出しのすべてのブランチをチェックする場合は、コードをいくつかの単純なステートメントif/elseに置き換えるだけです。if

つまり、代わりに:

if (condition1){
} else if (condition2){
} else if (condition3){
}

書きます

if (condition1){
} 
if (condition2){
} 
if (condition3){
}
于 2013-10-06T06:18:48.090 に答える