【问题标题】:Issues with Recursion递归问题
【发布时间】:2016-02-01 17:58:30
【问题描述】:

我在创建此递归方法时遇到问题。该方法需要将对象添加到堆栈中。

注意事项: 这是一个路径查找器项目。

getNextBird() 从鸟类对象内的鸟类队列中进行轮询。如果队列为空,则返回 null;如果它不为空,它将返回队列中的下一只鸟。

我根本不能使用任何循环。 (如果可以的话,这会很容易。) 堆栈中的最后一个元素必须是 Bird “end”。但是如果代码工作正常,它应该递归地完成。

我的问题是存在一种极端情况,即支票撞到墙,getNextBird 变为空(在本例中为对象鸟),我想从堆栈中弹出最新的对象。我会收到 StackOverflow 错误或 EmptyCollection 错误。

private static boolean recurse(Stack<Bird> path, Bird current, Bird end) 
{
    Bird bird = null;
    if (current != null) {
        bird = current.getNextBird();
        if (bird != null) {
            path.push(current);
            recurse(path, bird, end);
            return true;
        }
    }
    return false;
}

导入 java.util.Stack;

public class Solve2
{
  public static void main(String [] args)
  {
    // create the maze to solve
    Maze maze = new Maze();

    // create a Stack of Bird objects named path here
    Stack<Bird> path = new Stack<Bird>();

    // call recursive method to solve the maze and print the path
    recurse(path, maze.getStart(), maze.getEnd());
    print(path);
  }


  private static boolean recurse(Stack<Bird> path, Bird current, Bird end) 
  {
      Bird bird = null;
      if (current != null) {
          bird = current.getNextBird();
          if (bird != null) {
              path.push(current);
              recurse(path, bird, end);
              return true;
          } else {
              path.pop();
              recurse(path, path.peek(), end);
              return false;
          }
      }
      return false;  
  }


  private static void print(Stack<Bird> stack)
  {
    // write your code for recursively printing the stack here
 System.out.println(stack.pop());
 print(stack);

  }

}

鸟类:

public class Bird
{
  public static final int N  = 0;
  public static final int NE = 1;
  public static final int E  = 2;
  public static final int SE = 3;
  public static final int S  = 4;
  public static final int SW = 5;
  public static final int W  = 6;
  public static final int NW = 7;

  private static final String [] directions = {"N ", "NE", "E ", "SE", "S ", "SW", "W ", "NW"};

  private String name;
  private int direction;
  private Queue<Bird> queue;

  public Bird(int row, int column, int direction)
  {
    this.name = "Row/Column [" + row + "][" + column + "]";
    this.direction = direction;
  }

  public void setBirdQueue(Queue<Bird> queue)
  {
    this.queue = queue;
  }

  public String toString()
  {
    return "Location: " + name + ", Direction: " + directions[direction];
  }

  public int getDirection()
  {
    return this.direction;
  }
  public Bird getNextBird()
  {
    // write code to return the next Bird from the queue or null if no Birds left.
      return queue.poll();
  }
}

导入 java.util.LinkedList; 导入 java.util.Queue;

public class Maze
{
  private Bird start;
  private Bird end;

  public Maze()
  {
    // construct the diagrammed maze
    int MAX_ROW = 5;
    int MAX_COL = 7;
    Bird [][] maze = new Bird[MAX_ROW][MAX_COL];

    // row 0
    maze[0][0] = new Bird(0, 0, Bird.S);
    maze[0][1] = new Bird(0, 1, Bird.SW);
    maze[0][2] = new Bird(0, 2, Bird.S);
    maze[0][3] = new Bird(0, 3, Bird.SE);
    maze[0][4] = new Bird(0, 4, Bird.SW);
    maze[0][5] = new Bird(0, 5, Bird.SW);
    maze[0][6] = new Bird(0, 6, Bird.SW);

    // row 1
    maze[1][0] = new Bird(1, 0, Bird.S);
    maze[1][1] = new Bird(1, 1, Bird.W);
    maze[1][2] = new Bird(1, 2, Bird.SW);
    maze[1][3] = new Bird(1, 3, Bird.S);
    maze[1][4] = new Bird(1, 4, Bird.N);
    maze[1][5] = new Bird(1, 5, Bird.S);
    maze[1][6] = new Bird(1, 6, Bird.W);

    // row 2
    maze[2][0] = new Bird(2, 0, Bird.NE);
    maze[2][1] = new Bird(2, 1, Bird.NW);
    maze[2][2] = new Bird(2, 2, Bird.N);
    maze[2][3] = new Bird(2, 3, Bird.W);
    maze[2][4] = new Bird(2, 4, Bird.SE);
    maze[2][5] = new Bird(2, 5, Bird.NE);
    maze[2][6] = new Bird(2, 6, Bird.E);

    // row 3
    maze[3][0] = new Bird(3, 0, Bird.SE);
    maze[3][1] = new Bird(3, 1, Bird.NE);
    maze[3][2] = new Bird(3, 2, Bird.E);
    maze[3][3] = new Bird(3, 3, Bird.NW);
    maze[3][4] = new Bird(3, 4, Bird.NW);
    maze[3][5] = new Bird(3, 5, Bird.E);
    maze[3][6] = new Bird(3, 6, Bird.W);

    // row 4
    maze[4][0] = new Bird(4, 0, Bird.N);
    maze[4][1] = new Bird(4, 1, Bird.NE);
    maze[4][2] = new Bird(4, 2, Bird.N);
    maze[4][3] = new Bird(4, 3, Bird.N);
    maze[4][4] = new Bird(4, 4, Bird.NE);
    maze[4][5] = new Bird(4, 5, Bird.W);
    maze[4][6] = new Bird(4, 6, Bird.N);

    start = maze[2][0];
    end   = maze[2][6];

    // write your code here
    /*snipped the logic for adding the birds in the queue, but I do know that this part is 100% functional on my end*/
  }

  public Bird getStart()
  {
    return this.start;
  }

  public Bird getEnd()
  {
    return this.end;
  }

}

【问题讨论】:

  • 什么是Bird数据结构?你的输入数据是什么。也许您已经创建了某种循环并一次又一次地去同一只鸟?....在中间添加 System.out.println(bird) 对您很有用。
  • 您能否提供堆栈跟踪和边缘情况的示例?
  • @mst 它不会一遍又一遍地循环同一只鸟。
  • 这个方法怎么称呼。向我们展示输入数据。什么是鸟,开头的stack 是什么?
  • 更改递归(path, path.peek(), end);递归(路径,鸟,结束);

标签: java recursion stack


【解决方案1】:

好的,我看到你在递归中传递了参数end 但从未使用过它。

递归的一个关键是有一个控制语句,它将导致递归中断并返回正确的东西或什么都不返回。您已经随机返回 true 和 false(或者可能存在逻辑),这不会为您的执行路径添加任何值。

所以,让我们换一种方式:

  1. 除非您需要,否则不要将任何东西压入堆栈,这样您只需在打印时弹出。您需要推入堆栈的第一只鸟是与表达式(current == end) 匹配的final Bird
  2. 如果小鸟没有返回前一个小鸟的东西,表明路径被阻塞。现在与此匹配,在第 1 步中,如果 (current == end) 向前一只鸟返回一些东西,表明找到了最后一只鸟,并将链中的每只鸟都传递给第一只鸟。

伪代码:

recursive(stack, current, end)
{
    if(current == end){
        stack.push(current); //push the final bird
        return true; //indication that final is found
    }
    else if(current.getNext() != null){
        result = recurse(stack, current.getNext(), end); //recurse
        if(result == true)
          stack.push(current); // using indication from the chain

        return result; 
    }

    return false;
}

【讨论】:

  • 这是真的,你是对的!但我的问题是我将如何推送和弹出堆栈。因为在该方法中堆栈不应该变空,所以它应该只删除不需要的鸟对象。
  • 是什么让这只鸟不需要?
  • 因此,如果鸟队列中的下一只鸟(在每个鸟对象内,并且使用 getNextBird 调用)变为空,而没有到达最后一只鸟,那么该特定鸟对象将从堆。另外,您在代码周围使用的包装器的键盘快捷键是什么?
猜你喜欢
  • 2011-12-10
  • 2011-08-01
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多