簡體   English   中英

遞歸和if語句只返回負值

[英]Recursion and if statement only returns the negative value

所以這個問題實際上是與作業相關的 2 合 1 問題。 我必須編寫一個程序,從包含土地、水、沙袋和房屋瓷磚的文件中讀取 map 到二維數組和顯示 map 的 GUI。

當按下按鈕時,水磚會擴散到所有接觸它的土地和房屋瓷磚(水平、垂直和對角線),然后顯示一條消息,告訴您房屋是否被淹。

這必須通過遞歸方法來完成,我有一個程序大部分使用 8 個if語句,我認為這些語句效率極低,也不真正符合分配要求。 我怎么能讓這個遞歸?

我認為與我處理洪水問題的方式有關的第二個問題是,我檢查房子是否仍然站立的方法總是顯示房屋被淹的消息,即使房子是站立的。

幾天來我一直在嘗試解決這個問題,任何見解都將不勝感激。 (我以前也遇到過一個問題,即在我的checkForHouse方法中使用for循環會導致我的程序凍結並且必須通過任務管理器關閉,即使我沒有更改任何東西,它也會隨機停止這樣做,不確定這是否有幫助)。

public static void Flood(JLabel[][] labelArray, JPanel panel) {
    //Timer that allows the GUI to update slowly so progression can be seen
    ActionListener taskPerformer = new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        boolean running = true;
        while(running) {
            //Checks through the entire array to find water tiles 
            for (int i = 0; i < labelArray.length; i++) {
                for (int j = 0; j < labelArray[0].length; j++) {
                    if (labelArray[i][j].getText().equals("W")) {
                        if(i > 0 && (labelArray[i-1][j].getText().equals("L") || labelArray[i-1][j].getText().equals("H"))) {//Checks the tile left of the water tile
                            labelArray[i-1][j].setText("W");
                            labelArray[i-1][j].setBackground(Color.BLUE);
                        }
                        else if(j > 0 && (labelArray[i][j-1].getText().equals("L") ||labelArray[i][j-1].getText().equals("H"))) {//Checks the tile above the water tile
                            labelArray[i][j-1].setText("W");
                            labelArray[i][j-1].setBackground(Color.BLUE);
                        }
                        else if(i < labelArray.length-1 && (labelArray[i+1][j].getText().equals("L") || labelArray[i+1][j].getText().equals("H"))){//Checks the tile to the right of the water tile
                            labelArray[i+1][j].setText("W");
                            labelArray[i+1][j].setBackground(Color.BLUE);
                        }
                        else if(j < labelArray[0].length-1 && (labelArray[i][j+1].getText().equals("L") || labelArray[i][j+1].getText().equals("H"))) {//Checks the tile below the water tile
                            labelArray[i][j+1].setText("W");
                            labelArray[i][j+1].setBackground(Color.BLUE);
                            }       
                        else if(j < labelArray[0].length-1 && i < labelArray.length-1 && (labelArray[i+1][j+1].getText().equals("L") || labelArray[i+1][j+1].getText().equals("H"))) {//Checks the tile to the bottom right of the water tile
                            labelArray[i+1][j+1].setText("W");
                            labelArray[i+1][j+1].setBackground(Color.BLUE);
                        }
                        else if(j > 0 && i > 0 && (labelArray[i-1][j-1].getText().equals("L") || labelArray[i-1][j-1].getText().equals("H"))) {//Checks the tile to the top left of the water tile
                            labelArray[i-1][j-1].setText("W");
                            labelArray[i-1][j-1].setBackground(Color.BLUE);
                        }
                        else if(j > 0 && i < labelArray.length-1 && (labelArray[i+1][j-1].getText().equals("L") || labelArray[i+1][j-1].getText().equals("H"))) {//Checks the tile to the top right of the water tile
                            labelArray[i+1][j-1].setText("W");
                            labelArray[i+1][j-1].setBackground(Color.BLUE);
                        }
                        else if(j < labelArray[0].length-1 && i > 0 && (labelArray[i-1][j+1].getText().equals("L") || labelArray[i-1][j+1].getText().equals("H"))) {//Checks the tile to the bottom left of the water tile
                            labelArray[i-1][j+1].setText("W");
                            labelArray[i-1][j+1].setBackground(Color.BLUE);
                        }
                    }
                }
            }
            running = false;
            checkForHouse(labelArray);
        }
    }
    };
    new Timer(250, taskPerformer).start();
}

    public static void checkForHouse (JLabel[][] labelArray) {
    for (int r =0; r<labelArray.length; r++) {
        for (int c =0;c<labelArray[0].length; c++) {
            if(labelArray[r][c].getText().equals("H")) {
                textArea.setText(safeHouse);
            }
            else {
                textArea.setText(floodedHouse);
            }
        }
    }
}

根據評論更新

  1. 水可以一直流到邊界
  2. 水可以流到相鄰的土地或相鄰的房屋,它們變成水
  3. 水不能流到相鄰的沙袋
  4. 根據第3點,四面被沙袋包圍的水不會流動

從每個新填充的土地或房屋遞歸遍歷

  1. 使用 2 for 循環,遍歷所有單元格
  2. 對於任何具有“W”的單元格,請調用另一個 function
  3. 另一個 function 將遞歸更新任何相鄰的土地或房屋
final int[] x = new int[] {-1, -1, -1,  0,  0,  1,  1,  1};
final int[] y = new int[] {-1,  0,  1, -1,  1, -1   0,  1}; 

final char HOUSE = 'H'
final char LAND = 'L'; 
final char WATER = 'W';
final char WATERED_HOUSE = 'A';
final char WATERED_LAND = 'B'; 

final char SANDBAG = 'S'; // not used and is not needed

void process(char[][] input) {
  for (int row = 0; row < input.length; row++) {
    for (int col = 0; col < input[row].length; col++) {
      if (input[row][col] == WATER) {
        processNeighbor(input, row, col);
      }
    }
  }
  // if a cell is WATERED_HOUSE, then update text (if not done in processNeighbor function)
  for (int row = 0; row < input.length; row++) {
    for (int col = 0; col < input[row].length; col++) {
      if (input[row][col] == WATERED_HOUSE) {
        // set text
      }
      // if needed for WATERED_HOUSE and WATERED_LAND, 
      // change back to WATER and LAND respectively
    }
  }
}

void processNeighbor(char[][] input, final int row, final int col) {
  for (int adj = 0; adj < adjCount; adj++) {
    final int hor = col + x[adj];
    final int ver = row + y[adj];

    // stop recursion if neighbor is a not any one of house or land.
    if (!isValid(input, ver, hor) || !(input[ver][hor] == LAND || input[ver][hor] == HOUSE)) {
      continue;
    }

    // modify state to help recursion to end
    // if modification is not allowed, then maintain separate visited state
    if (input[ver][hor] == HOUSE) {
      input[ver][hor] = WATERED_HOUSE;
      // note: can set flooded here or in a separate loop later
    } else if (input[ver][hor] == LAND) {
      input[ver][hor] = WATERED_LAND;
    }

    // process any unprocessed neighbor recursively
    processNeighbor(input, ver, hor);
  }
}

// check whether given cell is within grid
boolean isValid(char[][] input, final int row, final int col) {
  return row >= 0 && row < input.length && col >= 0 && col < input[row].length;
}

原來的

以下邏輯假設水只會流向 1 個相鄰的瓷磚。 這是一個有效的假設嗎?

邏輯和bfs分離

  1. 使用附加標簽。 'A' 可以代表澆水的房子。
  2. 使用額外的 label 可簡化代碼並避免將“H”向前修改為“W”,隨后的迭代將錯誤地視為“W”(而它實際上是帶有“W”的“H”而不是最初的“W”)
  3. 如果在單元格中看到“W”,則在另一個外部 function 中的 2 個循環調用另一個 function
  4. 第二個 function 將運行帶有方向的 for 循環並更新相鄰位置(如果它們是“H”)
  5. 最后再運行一個 2 循環並將所有“A”更改為“W”並更改顏色
  6. 您也可以添加類似的土地檢查
// can make this an unmodifiable list to avoid accidental modification
//                         LU   L  LD   U   D  RU   R   RD
final int[] x = new int[] {-1, -1, -1,  0,  0,  1,  1,  1};
final int[] y = new int[] {-1,  0,  1, -1,  1, -1   0,  1}; 
final int adjCount = 8;
final char WATER = 'W';
final char HOUSE = 'H'
final char WATERED_HOUSE = 'A'; 

int process(char[][] input) {
  int count = 0; // this is just to track and for any optimization

  // initial processing to process cells adjacent to water
  for (int row = 0; row < input.length; row++) {
    for (int col = 0; col < input[row].length; col++) {
      if (WATER == input[row][col]) {
        count += processAdjacents(input, row, col);
      }
    }
  }

  final int modified = count;

  // second round to set watered house to water and color
  for (int row = 0; row < input.length; row++) {
    // if needed can use count == 0 to break;
    for (int col = 0; col < input[row].length; col++) {
      // if needed can use count == 0 to break;

      if (WATERED_HOUSE == input[row][col]) {
        input[row][col] = WATER;
        // set background color also
        count--;
      }
    }  
  }
  return modified;
}

// process adjacent cells of water cell
int processAdjacents(char[][] input, final int row, final int col) {
  int count = 0;
  for (int adj = 0; adj < adjCount; adj++) {
    final int hor = col + x[adj];
    final int ver = row + y[adj];
    
    if (isValid(input, ver, hor) && HOUSE == input[ver][hor]) {
      input[ver][hor] = WATERED_HOUSE;
      count++;
    }
  }
  return count;
}

// check whether given cell is within grid
boolean isValid(char[][] input, final int row, final int col) {
  return row >= 0 && row < input.length && col >= 0 && col < input[row].length;
}

免責聲明

  1. 未經測試的代碼並輸入 SO
  2. 沒有使用 DFS
  3. 土地未處理

暫無
暫無

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

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