簡體   English   中英

遞歸迷宮求解器問題

[英]Recursive Maze Solver Issue

我正在goNorth()一個遞歸Java迷宮程序,在調用子例程goNorth()goWest()goEast()goSouth() 基本上,我的問題涉及以下事實:它調用了一個子例程,但是在該子例程中,if和else語句沒有對我的其他子例程起作用,因此不會使它在其他可能性上起作用。 請協助,感謝您即將收到的答復。

import java.util.*;
import java.io.*;

public class RecursiveMazeSolverv2 {

  static Scanner in;
  static int row = 0;
  static int col = 0;
  static char maze[][];
  static int rowSize = 0;
  static int colSize = 0;
  static boolean success = true;

  public static void main(String[] args) {

    while (true) {
      try {
        in = new Scanner(new File("Maze1.txt")); 
        break;
      }
      catch (FileNotFoundException e) {
        System.out.println("Wrong File"); 
      }
    }
    rowSize = Integer.parseInt(in.nextLine());
    colSize = Integer.parseInt(in.nextLine());

    maze = new char[rowSize][colSize];

    String lineOfInput = "";
    for (int i = 0; i < maze.length; i++) {
      lineOfInput = in.nextLine();
      for (int j = 0; j < maze.length; j++) {
        maze[i][j] = lineOfInput.charAt(j);
      }
    }

    displayGrid();

    for (int i = 0; i < maze.length; i++) {
      for (int j = 0; j < maze.length; j++) {
        if (maze[i][j] == 'S') {
          maze[i][j]='+';
          System.out.println("Starting coordinates: " + i + ", " + j);
          row = i;
          col = j;
        }
      }
    }

if (goNorth(row, col))
  displayGrid();
else
  System.out.println("Impossible!");
  }


  static Boolean goNorth(int row, int col) {
    if (maze[row][col] == '.') {
      maze[row][col] = '+';
      return goNorth(row -1, col);
    }

    else if (maze[row][col] == 'G') {
      return true;
    }

    else {
      success = goNorth(row, col);
      if (success == false) {
        success = goWest(row, col -1); 
      }
      if (success == false) {
        success = goEast(row, col +1); 
      }
      if (success == false) {
        success = goSouth(row +1, col); 
      }
      if (success == false) {
        maze[row][col] = '.';
        success = false; }
      return false; 
    }

  }
   static Boolean goWest(int row, int col) {
    if (maze[row][col] == '.') {
      maze[row][col] = '+';
      return goWest(row, col -1);
    }

    else if (maze[row][col] == 'G') {
      return true;
    }

    else {
     success = goWest(row, col);
      if (success == false) {
        success = goNorth(row -1, col); 
      }
      if (success == false) {
        success = goSouth(row +1, col); 
      }
       if (success == false) {
        success = goEast(row, col -1); 
       }
      if (success == false) {
        maze[row][col] = '.';
        success = false; }
      return false; 
    }

  }

   static Boolean goEast(int row, int col) {
    if (maze[row][col] == '.') {
      maze[row][col] = '+';
      return goEast(row, col +1);
    }

    else if (maze[row][col] == 'G') {
      return true;
    }

    else {
     success = goEast(row, col);
      if (success == false) {
        success = goNorth(row -1, col); 
      }
      if (success == false) {
        success = goSouth(row +1, col); 
      }
       if (success == false) {
        success = goWest(row, col -1); 
       }
      if (success == false) {
        maze[row][col] = '.';
        success = false; }
      return false; 
    }

  }


   static Boolean goSouth(int row, int col) {
    if (maze[row][col] == '.') {
      maze[row][col] = '+';
      return goSouth(row +1, col);
    }

    else if (maze[row][col] == 'G') {
      return true;
    }

    else {
     success = goSouth(row, col);
      if (success == false) {
        success = goNorth(row -1, col); 
      }
      if (success == false) {
        success = goWest(row, col -1); 
      }
       if (success == false) {
        success = goEast(row, col +1); 
       }
      if (success == false) {
        maze[row][col] = '.';
        success = false; }
      return false; 
    }

  }

  public static void displayGrid() {
    for (int j = 0; j < maze.length; j++) {
      for (int k = 0; k < maze.length; k++) {
        System.out.print(maze[j][k] + " "); 
      }
      System.out.println();
    }
  }
}

抱歉,我無法在此處發布實際的迷宮,它不會正確顯示。

我看到的問題:

  1. 正如其他人所躲避的那樣,您不應使所有內容都保持static 無需進行冗長而無聊的討論,將所有內容設為static意味着您在遞歸調用中設置的值將修改所有調用的值。 您實際上正在使用在后續遞歸調用中設置的值來覆蓋每個遞歸調用。 您將需要使用大多數這些方法范圍的變量,以便該值僅在該方法調用的范圍內有效。
  2. 您的遞歸調用順序不同。 您每次都需要在同一步驟中進行相同的呼叫:先嘗試北,然后再進行南,然后再進行東,再進行西。 無論選擇哪種順序,呼叫都必須以相同的順序進行。 實際上,我不太確定為什么您決定為每個方向使用單獨的方法...為什么沒有一種稱為“移動”的方法嘗試先向北,然后遞歸,然后嘗試向南,然后遞歸,然后再嘗試向東遞歸,然后向西遞歸。 您對事物進行編碼的方式無法確定代碼在迷宮中的去向,並且很可能最終會繞圈走動。
  3. 這與無法使用的原因沒有直接關系,但是您確實需要處理代碼格式,尤其是制表符。 您的代碼看起來無處不在。 我只能想象,這使得解決問題變得更加困難。

編輯-示例

我將嘗試以某種方式指導您而不給您復制/粘貼答案,因此這將是偽代碼。

/**
 * My move recursion
 */
public boolean move(int currRow, int currCol) {
  // See if we solved it...
  if (solved) {
    return true;
  }

  // Try to go north first...
  if (maze[currRow-1][currCol] == '.') {
    if (move(int currRow-1, currCol)) {
      // Mark this with the "good" path and return true
    }
  }

  // Try to go east next...
  if (maze[currRow][currCol+1] == '.') {
    if (move(int currRow, currCol+1)) {
      // Mark this with the "good" path and return true
    }
  }

  // Try to go south next...
  if (maze[currRow+1][currCol] == '.') {
    if (move(int currRow+1, currCol)) {
      // Mark this with the "good" path and return true
    }
  }

  // Try to go west...
  if (maze[currRow][currCol-1] == '.') {
    if (move(int currRow, currCol-1)) {
      // Mark this with the "good" path and return true
    }
  }

  return false;
}

因此,基本上,我們檢查是否“已解決”。 如果沒有,看看我們是否可以向北走。 如果可以,請查看下一個呼叫是否已解決。 重復東部,南部和西部。 最終,其中一個遞歸調用將達到已解決的條件,這將觸發每個遞歸調用傳遞內部if,這會標記迷宮並返回true,從而產生連鎖反應,最終連鎖反應彈出調用堆棧,直到您完成了遞歸操作。

遞歸注意事項:

  1. 它通常需要是一個可以分解為一個或多個可重復的自主步驟的過程。 這並不意味着它必須是一個方法,但是如果是多個方法,則您必須以相同的順序在該方法中執行操作。 否則,您的邏輯將不同步。
  2. 當您可以將“步驟”分解為最小,最容易處理的部分時,通常效果最佳。 過於復雜的遞歸方法會導致難以調試以及大量瘋狂的分支和循環。
  3. 您必須有一個非常清楚的“結束”,否則您將遞歸直到炸毀堆棧。
  4. 在“方法級別”的變量/數據/信息與“全局”的變量/數據/信息之間應該有非常清楚的區別。 在您的情況下,迷宮是全球性的,成功和當前位置則不是。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM