【问题标题】:Java Recursion Over A Text File文本文件上的 Java 递归
【发布时间】:2013-11-22 22:53:04
【问题描述】:

我有一个代表建筑物的文本文件。建筑有楼层,楼层有房间。

一楼是0楼。

文本文件的结构如下:

Description
Image
North
East
South
West
Up
Down

North、East、South、West、Up 和 Down 是整数,表示该方向通向的房间。整数-1用于表示该方向没有出口。

根据建筑物的房间数量重复此操作。

所以对于四个房间,文本文件的内容可能是:

this is room 0
somefilepath
1
-1
-1
-1
2
-1
this is room 1
somefilepath
-1
-1
-1
0
-1
-1
this is room 2
somefilepath
-1
-1
-1
-1
3
0
this is room 3
somefilepath
-1
-1
-1
-1
-1
2

我正在尝试编写一个递归函数,它允许我根据 up 值计算建筑物的楼层数。例如,如果我们有一个房间上升到房间 1,房间 1 上升到房间 2,并且没有其他房间比这更高,那么我们知道有 3 层。

我知道如何使用 BufferedReader 或 Scanner 对象来读取文本文件,但我关心的是递归。

我想提前说声谢谢,这里的社区很棒。

我计算楼层数的方法(不完整,可能有误):

public int calculateFloors(int previousUp, int currentRoom) {
    Scanner scanner;
    int total = 0;
    try {
        scanner = new Scanner(currentMap);
        while (scanner.hasNextLine()) {
            scanner.nextLine();
            scanner.nextLine();
            scanner.nextLine();
            scanner.nextLine();
            scanner.nextLine();
            scanner.nextLine();
            int up = Integer.parseInt(scanner.nextLine());
            scanner.nextLine();
            if (up > 0) {
                // do something
                if (currentRoom == previousUp) {
                    // do something
                }
            }
            currentRoom++;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return total;   
}

【问题讨论】:

  • 标准问题:您尝试过什么?你有什么问题?您是否有一些代码可以显示您的想法以及它在什么方面不起作用?
  • @vanza 到目前为止,我已经发布了我的方法,如您所见,我不确定如何实现递归。
  • 递归的定义是根据自身定义的方法。在编程方面,它是一种调用自身的方法。 dummies.com/how-to/content/…
  • @James 感谢您的链接,我知道我需要在自身内部调用该函数,这就是为什么我有这两个参数来跟踪值的原因。我只是不确定如何将其应用于这种情况。
  • 我个人认为不需要递归方法...

标签: java file-io recursion


【解决方案1】:

好的,我编辑了我的想法:

那么我们需要做的: 我们访问每个房间,并从该房间遵循所有可能的方式。如果我们上升,我们添加 +1,如果我们下降,我们减去 -1,如果我们保持在同一水平,我们不增加一个值。 此外,我们需要跟踪已经访问过的房间,以免进入循环。

public int calculateFloors(int current, Set<Integer> visited) {
    int floors = 0;

    // get the values of the directions (add your code here to get them)
    int north = Integer.parseInt(scanner.nextLine()); 
    int east = Integer.parseInt(scanner.nextLine()); 
    int west = Integer.parseInt(scanner.nextLine()); 
    int south = Integer.parseInt(scanner.nextLine()); 
    int down = Integer.parseInt(scanner.nextLine()); 
    int up = Integer.parseInt(scanner.nextLine()); 


    if (up > 0 && !visited.contains(up)) {
        visited.add(up);
        floors = calculateFloors(up, visited) + 1;
    }

    if (down > 0 && !visited.contains(down)) {
        visited.add(down);
        int result = calculateFloors(down, visited) - 1;
        floors = result > floors ? result : floors;
    }

    if (north > 0 && !visited.contains(north)) {
        visited.add(north);
        int result = calculateFloors(norht, visited);
        floors = result > floors ? result : floors;
    }

    if (south > 0 && !visited.contains(south)) {
        visited.add(south);
        int result = calculateFloors(south, visited);
        floors = result > floors ? result : floors;
    }
    if (west > 0 && !visited.contains(west)) {
        visited.add(west);
        int result = calculateFloors(west, visited);
        floors = result > floors ? result : floors;
    }
    if (east > 0 && !visited.contains(east)) {
        visited.add(east);
        int result = calculateFloors(east, visited);
        floors = result > floors ? result : floors;
    }


    return floors;
}

这应该可以(只需添加代码以查找当前房间的方向值)在我的意见中。

【讨论】:

  • 基本情况在哪里?
  • 它似乎无限期地继续下去
  • 我还没有测试过,这就是我会做的。但它应该在没有更多楼层时终止,即当 up 等于 -1
  • @Edgar,但必须对每个房间都这样做,因为您没有检查是否有从相邻房间向上的路。
  • 好的,现在我明白了这里的整个问题。让我考虑一下
【解决方案2】:
public int calculateFloors(int count) {
    Scanner scanner;
    int count=1;
    try {
        scanner = new Scanner(currentMap);
        //uses count to work out what rooms we can skip 
        for(int i=0;i<count*6)
            scanner.nextLine();
        //gets the value of up
        int up = Integer.parseInt(scanner.nextLine());
        //our base case --- if there are no more floors, return the number --- otherwise perform the recursive call.
        if(up==-1)
            return count;
        else
            count+=calculateFloors(count++);
    }catch(Exception e){
        System.out.println(e);
    }
    return count;   
}

试试看。

【讨论】:

  • 我跳过房间的逻辑是错误的,但这是你可以微调的
  • 更新了帖子以按预期工作,错过了一个 ++ 运算符;)
  • 你也不能有参数计数以及局部变量计数。哪个是哪个?此外,您的 for 循环缺少增加 i 的第三部分。而且我很确定您不想将计数乘以 6。它永远只是 6 :)
  • 大声笑,我很愚蠢,没有文件就无法精炼,摆脱 int count = 1!调用方法时,传入一个参数1即可。抱歉
【解决方案3】:

只需对房间进行深度优先搜索(您不需要递归函数)。您可能会上下爬到顶部。

public static class Room {
  public final int[] neighborsSameFloor; // indices of the rooms on the same floor
  public final int neighborUp; // index of the room above
  public final int neighborDown; // index of the room below
  public Room(/*???*/) {
    // do the initialisation
  }
}

public Room[] readRooms() {
  // read file here
}

public int getEntry() {
  // returns the first room to enter
}

public int calculateFloorCount() {
  Room[] rooms = readRooms();
  int currentRoomIndex = getEntry();
  int minFloor = 0;
  int maxFloor = 0;
  int roomFloors[] = new int[rooms.length];
  boolean[] visited = new boolean[rooms.length];
  Stack<Integer> roomStack = new Stack<>();
  roomStack.push(currentRoomIndex);
  // roomFloors[currentRoom] = 0;
  // Arrays.fill(visted, false); both should happen automatically when the arrays are initialized

  while (!roomStack.empty()) {
    currentRoomIndex = roomStack.pop();
    // ignore already visited rooms
    if (visited[currentRoomIndex]) continue;
    visited[currentRoomIndex] = true;
    Room room = rooms[currentRoomIndex];
    int currentFloor = roomFloors[currentRoomIndex];

    if (currentFloor > maxFloor)
      maxFloor = currentFloor;
    else if (currentFloor < minFloor)
      minFloor = currentFloor;

    // add room one floor up
    if (room.neighborUp >= 0 && !visited[room.neighborUp]) {
      roomFloors[room.neighborUp] = currentFloor+1;
      roomStack.push(room.neighborUp);
    }

    // add room one floor down
    if (room.neighborDown >= 0 && !visited[room.neighborDown]) {
      roomFloors[room.neighborDown] = currentFloor-1;
      roomStack.push(room.neighborDown);
    }

    // add rooms on the same floor
    for (int i = 0; i < room.neighborsSameFloor.length; i++) {
      int index = room.neighborsSameFloor[i];
      roomFloors[index] = currentFloor;
      roomStack.push(index);
    }
  }

  return maxFloor-minFloor+1;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-28
    • 2011-01-04
    • 2018-01-05
    • 2010-11-30
    • 2016-12-30
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多