Ciphor
Ciphor

Reputation: 742

Java Recursion Over A Text File

I have a text file that represents a building. A building has floors, and floors have rooms.

The first floor is floor 0.

The text file is structured like so:

Description
Image
North
East
South
West
Up
Down

Where North, East, South, West, Up and Down are integers denoting the room that direction leads to. The integer -1 is used to denote that there is no exit in that direction.

This is repeated for the number of rooms the building has.

So for four rooms the contents of the text file may be:

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

I'm trying to write a recursive function that will allow me to calculate the number of floors in the building based on the up values. For example, if we have a room that goes up to room 1, and room 1 goes up to room 2 and that no other rooms go higher than this then we know that there are 3 floors.

I know how to use either a BufferedReader or Scanner object to read the text file but the recursion is what I'm concerned about.

I want to say thank-you in advance, the community here is amazing.

My method to calculate the number of floors (incomplete and may be wrong):

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;   
}

Upvotes: 0

Views: 150

Answers (3)

Blub
Blub

Reputation: 3822

Ok I edited my idea:

So what we need to do: We visit each room and follow all possible ways from that room. If we go up we add +1, if we go down we substract -1 and if we stay on the same level we dont add a value. Also we need to keep track for the rooms already visited to not go in cycles.

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;
}

This should work (just add the code to find the directions values of the current room) in my opinioin.

Upvotes: 1

fabian
fabian

Reputation: 82491

Just do a Depth-First-Search over the rooms (you do not need a recursive function). You might go up and down to reach the top.

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;
}

Upvotes: 0

James
James

Reputation: 359

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;   
}

Try that.

Upvotes: 0

Related Questions