Complete the Flight practice problem before reviewing the solution.
Review the Flight
solution with AP CS Tutor Brandon Horn.
Part (a) frequentFlyers
method
public ArrayList<String> frequentFlyers()
{
ArrayList<String> frequentFlyers = new ArrayList<String>();
for (int row = 0; row < rows; row++)
for (int seat = 0; seat < seatsPerRow; seat++)
if (seats[row][seat] != null && seats[row][seat].isFrequentFlyer())
frequentFlyers.add(seats[row][seat].passengerName());
return frequentFlyers;
}
This method requires only a simple traversal of the entire 2D array. Traversal of a 2D array is often easily accomplished using a nested for
loop, which allows both access to and modification of each element. In this case, each reservation is checked for frequent flyer status and the names of frequent flyers are added to the list to be returned.
The instance fields rows
and seatsPerRow
could be replaced with seats.length
and seats[0].length
, respectively.
Part (b) reserveAdjacentSeats
method
public boolean reserveAdjacentSeats(String passOneName, String passTwoName)
{
for (int row = 0; row < rows; row++)
{
for (int seat = 1; seat < seatsPerRow; seat++)
{
if (seats[row][seat - 1] == null && seats[row][seat] == null)
{
seats[row][seat - 1] = new Reservation(passOneName);
seats[row][seat] = new Reservation(passTwoName);
return true;
}
}
}
return false;
}
All rows must be traversed as usual; however, each row must be traversed carefully to avoid exceeding the array bounds. Checking for adjacent empty seats requires checking 2 array positions for each run of the inner loop. If the loop traversed the entire row as usual, it would exceed the bounds at either the first or the last element.
When possible, I prefer to start my loops at an unusual value rather than end them at an unusual value. In this method, my inner loop starts at 1 rather than 0 and checks each seat and the seat prior to it.
Part (c) reserveWindowSeat
method
public boolean reserveWindowSeat(String passengerName)
{
for (int row = 0; row < rows; row++)
{
if (seats[row][0] == null)
{
seats[row][0] = new Reservation(passengerName);
return true;
}
if (seats[rows][seatsPerRow - 1] == null)
{
seats[row][seatsPerRow - 1] = new Reservation(passengerName);
return true;
}
}
return false;
}
Window seats are defined as those in columns 0
or seatsPerRow - 1
. Those seats must be checked in each row. There is no nested loop because only 2 specific seats must be checked in each row.
Part (d) isolatedPassengers
method
public ArrayList<String> isolatedPassengers()
{
ArrayList<String> isolatedPassengers = new ArrayList<String>();
for (int row = 0; row < rows; row++)
{
if (seats[row][0] != null && seats[row][1] == null)
isolatedPassengers.add(seats[row][0].passengerName());
for (int seat = 1; seat <= seatsPerRow - 2; seat++)
{
if (seats[row][seat] != null &&
seats[row][seat - 1] == null &&
seats[row][seat + 1] == null)
isolatedPassengers.add(seats[row][seat].passengerName());
}
if (seats[row][seatsPerRow - 1] != null && seats[row][seatsPerRow - 2] == null)
isolatedPassengers.add(seats[row][seatsPerRow - 1].passengerName());
}
return isolatedPassengers;
}
The outer loop traverses all rows as usual. The first and last seats in each row have only 1 adjacent seat each, so they must be checked separately. Each middle seat has 2 adjacent seats (one on each side). The bounds for the loop that traverses the middle seats must exclude both the first and last seat to prevent a bounds error. Three seats must be checked for each iteration of the inner loop (the seat at position seat
, and each of the 2 adjacent seats).
Additional 2D array resources
- Intro to 2D arrays
- 2D array exercises
- Mazer FR
- Droppy FR
- MatrixManipulator exercise
- DeterminantFinder exercise