Q2: [BusRouteSearchEngine Mini-Project] Create a RouteManager class. This class
ID: 3809343 • Letter: Q
Question
Q2: [BusRouteSearchEngine Mini-Project] Create a RouteManager class. This class will store instances of the BusRoute class, and support generating a list of potential itineraries. It should contain one constructor, two instance variables (an array of BusRoutes, and something that counts the number of bus routes in the system), and four methods (addBusRoute, increaseSize, findItineraries, shrinkItineraries). [25 points]
default constructor: will set up the instances variables with zero bus routes.
addBusRoute(...): Adds a bus route to the bus routes array. Uses the increaseSize() method if the array is full.
increaseSize(): Doubles the size of the bus routes array, while keeping whatever is already there. Make this a private method.
findItineraries(...): Searches the bus routes based on source bus station, destination bus station, and departure time, to find 1-bus route and 2-bus route itineraries meeting those criteria. When searching for 2-bus route itineraries, checks that the bus routes have a connecting city, and that the first arrives in time for the second. Your method should create an array of potential itineraries that can be returned. (If it helps, you may assume that this method will never find more than 100 itineraries.) Use the shrinkItineraries() method to "clean up" up the potential itineraries array; see below. Hint: use loops to search for all the bus routes in the bus routes variable, check if they meet the criteria, and then create a new Itinerary object if the criteria is met.
shrinkItineraries(...). Takes an array of itineraries, where some of the later indices are unused (null), and returns a new array of itineraries where there are no empty indices. Make this a private method.
BUS:
public class Bus {
BusType busType;
String model;
public Bus(BusType busType, String model) {
this.busType = busType;
this.model = model;
}
public BusType getBusType() {
return this.busType;
}
public String getModel() {
return this.model;
}
@Override
public String toString() {
return this.busType + " * " + this.model;
}
public String toStringWithNumber(String routeNumber) {
return this.busType + " " + routeNumber + " * " + this.model;
}
}
Bus Route:
import java.text.NumberFormat;
public class BusRoute {
Bus bus;
String routeNumber;
double routeCost;
Time departureTime;
int durationTime;
BusStation sourceBusStation;
BusStation destinationBusStation;
public BusRoute(Bus bus, String routeNumber, double routeCost, Time departureTime, int durationTime,
BusStation sourceBusStation, BusStation destinationBusStation) {
this.bus = bus;
this.routeNumber = routeNumber;
this.routeCost = routeCost;
this.departureTime = departureTime;
this.durationTime = durationTime;
this.sourceBusStation = sourceBusStation;
this.destinationBusStation = destinationBusStation;
}
public Bus getBus() {
return bus;
}
public String getNumber() {
return routeNumber;
}
public double getCost() {
return routeCost;
}
public BusStation getDestination() {
return destinationBusStation;
}
public Time getDeparture() {
return departureTime;
}
public Time getArrival() {
Time arrivalTime = new Time(departureTime.getHour(), departureTime.getMinute());
arrivalTime.addMinutes(durationTime);
return arrivalTime;
}
public BusStation getSource() {
return sourceBusStation;
}
public String toOverviewString() {
NumberFormat nf = NumberFormat.getCurrencyInstance();
String output = nf.format(routeCost) + " " + getDeparture() + " - ";
output += getArrival() + " " + durationTime / 60 + "h:" + durationTime % 60 + "m";
output += " " + bus.getBusType() + " " + sourceBusStation + "-" + destinationBusStation;
return output;
}
public String toDetailedString() {
String output =
getDeparture() + " - " + getArrival() + " " + BusStation.getBusStationCity(sourceBusStation) + " (" +
sourceBusStation + ") - " + BusStation.getBusStationCity(destinationBusStation) + " (" + destinationBusStation + ")" +
" " + bus.getBusType() + " " + routeNumber + " * " + bus.getModel();
return output;
}
}
Bus Station:
public enum BusStation {
PHX,
LAX,
LVS,
SAN,
SFO,
YUM;
public static String getBusStationCity(BusStation busStation) {
switch (busStation) {
case PHX:
return "Phoenix";
case LAX:
return "Los Angeles";
case LVS:
return "Las Vegas";
case SAN:
return "San Diego";
case SFO:
return "San Fransisco";
default:
return "Unknown City";
}
}
}
Bus Type:
public enum BusType {
Greyhound,
BoltBus,
Megabus;
}
Time:
public class Time {
int hour;
int minute;
public Time(int hour, int minute) {
this.hour = hour;
this.minute = minute;
}
public Time() {
this.hour = 12;
this.minute = 0;
}
public int getHour() {
return this.hour;
}
public int getMinute() {
return this.minute;
}
public void addHours(int hoursToAdd) {
this.hour = ((this.hour + hoursToAdd % 24) + 24) % 24;
}
public void addMinutes(int minutesToAdd) {
this.minute += minutesToAdd;
this.minute = ((this.minute % (24*60)) + (24*60)) % (24*60);
this.addHours((int) Math.floor(((double)this.minute)/(60.0)));
this.minute = this.minute % 60;
}
public void addTime(Time timeToAdd) {
this.addHours(timeToAdd.hour);
this.addMinutes(timeToAdd.minute);
}
public Time getCopy() {
return new Time(this.hour, this.minute);
}
public boolean isEarlierThan(Time timeToCompare) {
if (hour < timeToCompare.getHour()) {
return true;
}
else {
return false;
}
}
public boolean isSameTime(Time timeToCompare) {
if ((this.hour==timeToCompare.hour) && (this.minute==timeToCompare.minute)) {
return true;
}
else {
return false;
}
}
public boolean isLaterThan(Time timeToCompare) {
if (hour > timeToCompare.getHour()) {
return true;
}
else {
return false;
}
}
private String formatDigits(int i) {
boolean negative = false;
if (i < 0)
negative = true;
int positiveMinutes = Math.abs(i);
int hours = (int) Math.floor(((double)positiveMinutes)/(60.0));
int minutes = positiveMinutes % 60;
String hourMinuteString = hours + "h:" + minutes + "m";
if (negative) {
hourMinuteString = "-(" + hourMinuteString + ")";
}
return hourMinuteString;
}
@Override
public String toString() {
int twelveHour = ((this.hour-1) % 12 + 12) % 12 + 1;
String minuteString = String.format("%02d",this.minute);
String meridiem;
if (this.hour<=11) {
meridiem = "AM";
} else {
meridiem = "PM";
}
return twelveHour + ":" + minuteString + meridiem;
}
}
Explanation / Answer
JAVA CODE:
import java.text.NumberFormat;
public class RouteManager{
BusRoute[] routes;
int size;
public RouteManager(){
size=0;
routes=new BusRoute[size];
}
public void addBusRoute(BusRoute busRoute){
if(size==routes.length)
increaseSize();
routes[size]=busRoute;
size= size+1;
}
private void increaseSize(){
BusRoute[] tmp;
if(size==0)
tmp = new BusRoute[1];
else
tmp=new BusRoute[2*routes.length];
System.arraycopy(routes,0,tmp,0,routes.length);
this.routes = tmp;
}
public String[] findItineraries(BusStation sourceStation,BusStation destinationStation,Time departure){
String[] potentialItineraries=new String[100];//itineraries stored as strings
int noOfItineraries=0;
for(int i=0;i<size;i++){
//find all 1-route if source ,destination and departure match
if(routes[i].getSource().equals(sourceStation)&&routes[i].getDestination().equals(destinationStation)&&routes[i].getDeparture().isSameTime(departure)){
String itinerary="1-Bus Route ";
itinerary += routes[i].toDetailedString()+" .................................";
if(noOfItineraries<100){//if itineraries >100 skip
potentialItineraries[noOfItineraries]=itinerary;
noOfItineraries++;
}
}
for(int j=0;j<size;j++){
//find all 2 routes.
if(i!=j&&routes[i].getSource().equals(sourceStation)&&routes[j].getDestination().equals(destinationStation)&&routes[i].getDeparture().isSameTime(departure)&&(routes[i].getArrival().isEarlierThan(routes[j].getDeparture())))
{
String itinerary="2-Bus Route ";
itinerary+=routes[i].toDetailedString()+" "+routes[j].toDetailedString()+" ............................";
if(noOfItineraries<100){
potentialItineraries[noOfItineraries]=itinerary;
noOfItineraries++;
}
}
}
}
String[] shrinkedItineraries=shrinkItineraries(potentialItineraries,noOfItineraries);
return shrinkedItineraries;
}
private String[] shrinkItineraries(String[] potential,int length ){
String[] temp=new String[length];//create a new array of length 'length'
System.arraycopy(potential,0,temp,0,length);//copy to new array and return
return temp;
}
public static void main(String[] args){
Bus bus1=new Bus(BusType.BoltBus,"model1");
Bus bus2=new Bus(BusType.Megabus,"model2");
Bus bus3=new Bus(BusType.Greyhound,"model3");
Bus bus4=new Bus(BusType.Greyhound,"model4");
BusRoute route1=new BusRoute(bus1,"15240",1802.50,new Time(4,50),60,BusStation.PHX,BusStation.LAX);
BusRoute route2=new BusRoute(bus2,"15287",600.50,new Time(6,0),120,BusStation.LAX,BusStation.SFO);
BusRoute route3=new BusRoute(bus3,"6458",2000,new Time(4,50),180,BusStation.PHX,BusStation.SFO);
BusRoute route4=new BusRoute(bus4,"12456",600.50,new Time(5,30),8,BusStation.LAX,BusStation.SFO);
HelloWorld l=new HelloWorld();
l.addBusRoute(route1);
l.addBusRoute(route2);
l.addBusRoute(route3);
l.addBusRoute(route4);
String[] itineraries=l.findItineraries(BusStation.PHX,BusStation.SFO,new Time(4,50));
if(itineraries.length==0)
{
System.out.println("No matching Itineraries!!!");
}else{
System.out.println("Printing all itineraries from Phoenix to San Fransisco departing at 4:50 AM ");
for(int i=0;i<itineraries.length;i++){
System.out.println(itineraries[i]);
}
}
}
}
class Bus {
BusType busType;
String model;
public Bus(BusType busType, String model) {
this.busType = busType;
this.model = model;
}
public BusType getBusType() {
return this.busType;
}
public String getModel() {
return this.model;
}
@Override
public String toString() {
return this.busType + " * " + this.model;
}
public String toStringWithNumber(String routeNumber) {
return this.busType + " " + routeNumber + " * " + this.model;
}
}
class BusRoute {
Bus bus;
String routeNumber;
double routeCost;
Time departureTime;
int durationTime;
BusStation sourceBusStation;
BusStation destinationBusStation;
public BusRoute(Bus bus, String routeNumber, double routeCost, Time departureTime, int durationTime,
BusStation sourceBusStation, BusStation destinationBusStation) {
this.bus = bus;
this.routeNumber = routeNumber;
this.routeCost = routeCost;
this.departureTime = departureTime;
this.durationTime = durationTime;
this.sourceBusStation = sourceBusStation;
this.destinationBusStation = destinationBusStation;
}
public Bus getBus() {
return bus;
}
public String getNumber() {
return routeNumber;
}
public double getCost() {
return routeCost;
}
public BusStation getDestination() {
return destinationBusStation;
}
public Time getDeparture() {
return departureTime;
}
public Time getArrival() {
Time arrivalTime = new Time(departureTime.getHour(), departureTime.getMinute());
arrivalTime.addMinutes(durationTime);
return arrivalTime;
}
public BusStation getSource() {
return sourceBusStation;
}
public String toOverviewString() {
NumberFormat nf = NumberFormat.getCurrencyInstance();
String output = nf.format(routeCost) + " " + getDeparture() + " - ";
output += getArrival() + " " + durationTime / 60 + "h:" + durationTime % 60 + "m";
output += " " + bus.getBusType() + " " + sourceBusStation + "-" + destinationBusStation;
return output;
}
public String toDetailedString() {
String output =
getDeparture() + " - " + getArrival() + " " + BusStation.getBusStationCity(sourceBusStation) + " (" +
sourceBusStation + ") - " + BusStation.getBusStationCity(destinationBusStation) + " (" + destinationBusStation + ")" +
" " + bus.getBusType() + " " + routeNumber + " * " + bus.getModel();
return output;
}
}
enum BusStation {
PHX,
LAX,
LVS,
SAN,
SFO,
YUM;
public static String getBusStationCity(BusStation busStation) {
switch (busStation) {
case PHX:
return "Phoenix";
case LAX:
return "Los Angeles";
case LVS:
return "Las Vegas";
case SAN:
return "San Diego";
case SFO:
return "San Fransisco";
default:
return "Unknown City";
}
}
}
enum BusType {
Greyhound,
BoltBus,
Megabus;
}
class Time {
int hour;
int minute;
public Time(int hour, int minute) {
this.hour = hour;
this.minute = minute;
}
public Time() {
this.hour = 12;
this.minute = 0;
}
public int getHour() {
return this.hour;
}
public int getMinute() {
return this.minute;
}
public void addHours(int hoursToAdd) {
this.hour = ((this.hour + hoursToAdd % 24) + 24) % 24;
}
public void addMinutes(int minutesToAdd) {
this.minute += minutesToAdd;
this.minute = ((this.minute % (24*60)) + (24*60)) % (24*60);
this.addHours((int) Math.floor(((double)this.minute)/(60.0)));
this.minute = this.minute % 60;
}
public void addTime(Time timeToAdd) {
this.addHours(timeToAdd.hour);
this.addMinutes(timeToAdd.minute);
}
public Time getCopy() {
return new Time(this.hour, this.minute);
}
public boolean isEarlierThan(Time timeToCompare) {
if (hour < timeToCompare.getHour()) {
return true;
}
else {
return false;
}
}
public boolean isSameTime(Time timeToCompare) {
if ((this.hour==timeToCompare.hour) && (this.minute==timeToCompare.minute)) {
return true;
}
else {
return false;
}
}
public boolean isLaterThan(Time timeToCompare) {
if (hour > timeToCompare.getHour()) {
return true;
}
else {
return false;
}
}
private String formatDigits(int i) {
boolean negative = false;
if (i < 0)
negative = true;
int positiveMinutes = Math.abs(i);
int hours = (int) Math.floor(((double)positiveMinutes)/(60.0));
int minutes = positiveMinutes % 60;
String hourMinuteString = hours + "h:" + minutes + "m";
if (negative) {
hourMinuteString = "-(" + hourMinuteString + ")";
}
return hourMinuteString;
}
@Override
public String toString() {
int twelveHour = ((this.hour-1) % 12 + 12) % 12 + 1;
String minuteString = String.format("%02d",this.minute);
String meridiem;
if (this.hour<=11) {
meridiem = "AM";
} else {
meridiem = "PM";
}
return twelveHour + ":" + minuteString + meridiem;
}
}
NOTE: copy the code to file named RouteManager.java . Compile and Run
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.