Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ B. 돌아가기

## 조회 결과
[INFO] ---
[INFO] 총 거리: 4km
[INFO] 총 소요 시간: 11분
[INFO] 총 거리: 6km
[INFO] 총 소요 시간: 14분
[INFO] ---
[INFO] 교대역
[INFO] 강남역
Expand Down
42 changes: 42 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
## 구현할 기능 목록

1. 메인 화면 출력하기 // 첫 실행시, 종료 입력이 주어지지 않으면 계속 다시 시작됨
2. 메인화면에서 원하는 기능 입력받기 // 경로 조회, 종료 기능 선택 가능
3. 경로 조회의 경로 기준 기능 항목 출력하기
4. 경로 기준에서 원하는 기능 입력받기 // 최단 거리, 최소 시간, 돌아가기 기능 출력 가능
5. 출발역과 도착역을 입력받기
6. 최단 거리로 경로 계산하기
7. 최소 시간으로 경로 계산하기
8. 조회 결과 출력하기


## 예외 처리

1. 기능 선택 화면에서 선택 가능 항목을 입력하지 않을 시 다시 선택 가능 항목을 보여주고 입력 받음
2. 출발역 입력시 출발역이 존재하지 않으면 예외를 발생시키고 다시 기능 선택 화면으로 돌아감
3. 도착역 입력시 도착역이 존재하지 않으면 예외를 발생시키고 다시 기능 선택 화면으로 돌아감
4. 출발역과 도착역이 동일할 시 예외를 발생시키고 다시 기능 선택 화면으로 돌아감


## 구현할 설정 목록

1. 사전 등록 정보 설정하기
2. 노선에서 역과 역 사이의 거리를 저장하는 리스트 생성
3. 노선에서 역과 역 사이의 소요 시간을 저장하는 리스트 생성.
*주의 사항* : 한 노선에서 갈래길은 없다고 가정한다.
그러면 해당 노선은 단방향이므로 특정 역에서는 다음 역으로 단 하나의 경로만 존재한다.
해당 노선의 특정 역에서 다음 역까지의 거리(시간)정보만 저장하면 해당 노선에서의 거리(시간) 정보를 파악할 수 있다.
환승역을 올바르게 고려하기 위해 노선에 추가되는 역은 이름이 동일하면 모든 노선에서 동일한 역으로 고려되어야 한다.


## 추후 고려 사항
1. 경로를 파악하기 위해 입력된 두 역이 연결되어 있는지 파악해야 한다.
getDijkstraShortestPath() 함수를 찾아보니 경로가 존재하지 않으면 getPath함수의 출력값을 null로 준다고 하는데
이것을 활용하여 예외처리를 할 수 있을지 고려해본다. (NullPointerException을 통해 예외처리 완료)


## 실패한 사항
해당 역마다 어떤 노선에 등록되어있는지 값을 저장하고
최종으로 구해진 결과에서 어떤 노선에 등록된 역인지를 구분하여 거리와 소요시간을 구하려 했는데
그렇게 하려면 setter를 사용해야 하므로
hash값을 조정하는 등 다른 방법을 계속 시도해 보았는데 시간내에 실패하고 말았습니다.
12 changes: 11 additions & 1 deletion src/main/java/subway/Application.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
package subway;

import java.util.Scanner;
import subway.controller.MainDashboard;
import subway.controller.RouteCalculator;
import subway.domain.Line;
import subway.domain.LineRepository;
import subway.domain.Station;
import subway.domain.StationRepository;
import subway.view.InputView;

public class Application {

public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
// TODO: 프로그램 구현
InputView inputView = new InputView(scanner);
new InitialMap();
MainDashboard mainDashboard = new MainDashboard(inputView);
}
}
47 changes: 47 additions & 0 deletions src/main/java/subway/InitialMap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package subway;

import subway.domain.Line;
import subway.domain.LineRepository;
import subway.domain.Station;
import subway.domain.StationRepository;

public class InitialMap {

public InitialMap() {
Station station1 = new Station("교대역");
Station station2 = new Station("강남역");
Station station3 = new Station("역삼역");
Station station4 = new Station("남부터미널역");
Station station5 = new Station("양재역");
Station station6 = new Station("양재시민의숲역");
Station station7 = new Station("매봉역");

StationRepository.addStation(station1);
StationRepository.addStation(station2);
StationRepository.addStation(station3);
StationRepository.addStation(station4);
StationRepository.addStation(station5);
StationRepository.addStation(station6);
StationRepository.addStation(station7);

Line line1 = new Line("2호선");
Line line2 = new Line("3호선");
Line line3 = new Line("신분당선");

LineRepository.addLine(line1);
LineRepository.addLine(line2);
LineRepository.addLine(line3);

line1.addStation(station1, 2, 3);
line1.addStation(station2, 2, 3);
line1.addStation(station3);
line2.addStation(station1, 3, 2);
line2.addStation(station4, 6, 5);
line2.addStation(station5, 1, 1);
line2.addStation(station7);
line3.addStation(station2, 2, 8);
line3.addStation(station5, 10, 3);
line3.addStation(station6);

}
}
39 changes: 39 additions & 0 deletions src/main/java/subway/SubwayKeyWords.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package subway;

public class SubwayKeyWords {

public static final String DASHBOARD_MAIN = "## 메인 화면";
public static final String DASHBOARD_ROUTE = "## 경로 기준";


public static final String OPTION_NUM_1 = "1";
public static final String OPTION_NUM_2 = "2";
public static final String OPTION_QUIT = "Q";
public static final String OPTION_BACK = "B";

public static final String DASHBOARD_MAIN_OPTION_1 = "경로 조회";

public static final String DASHBOARD_ROUTE_OPTION_1 = "최단 거리";
public static final String DASHBOARD_ROUTE_OPTION_2 = "최소 시간";

public static final String DASHBOARD_OPTION_Q = "종료";
public static final String DASHBOARD_OPTION_B = "돌아가기";

public static final String MESSAGE_CHOOSE_OPTION = "## 원하는 기능을 선택하세요.";
public static final String MESSAGE_CHOOSE_DEPARTURE_STATION = "## 출발역을 입력하세요.";
public static final String MESSAGE_CHOOSE_ARRIVAL_STATION = "## 도착역을 입력하세요.";

public static final String ERROR_OPTION_UNAVAILABLE = "[ERROR] 선택할 수 없는 기능입니다.";
public static final String ERROR_STATION_UNREACHABLE = "[ERROR] 출발역과 도착역이 연결되어 있지 않습니다.";
public static final String ERROR_STATION_NOT_EXISTS = "[ERROR] 존재하지 않는 역입니다.";
public static final String ERROR_STATION_SAME_NAME = "[ERROR] 출발역과 도착역이 동일합니다.";

public static final String INFO_LINE = "[INFO] ---";
public static final String INFO_TOTAL_DISTANCE = "[INFO] 총 거리: %dkm\n";
public static final String INFO_TOTAL_TIME = "[INFO] 총 소요 시간: %d분\n";
public static final String INFO_STATION_NAME = "[INFO] %s\n";

public static final String RESULT_ANNOUNCEMENT = "## 조회 결과";


}
64 changes: 64 additions & 0 deletions src/main/java/subway/controller/MainDashboard.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package subway.controller;

import static subway.SubwayKeyWords.*;

import java.util.TreeMap;
import subway.exceptions.ExceptionOptionUnavailable;
import subway.view.InputView;
import subway.view.OutputView;

public class MainDashboard {

public static String title = DASHBOARD_MAIN;
TreeMap<String, String> options;
InputView inputView;
boolean power;

public MainDashboard(InputView inputView) {
this.inputView = inputView;
power = true;
options = new TreeMap<>();
options.put(OPTION_NUM_1, DASHBOARD_MAIN_OPTION_1);
options.put(OPTION_QUIT, DASHBOARD_OPTION_Q);
startMainDashboard(inputView);
}

public void startMainDashboard(InputView inputView) {
while (power) {
String chosenOption = makeUserChooseOption(inputView);
startChosenOption(chosenOption);
}
}


public String makeUserChooseOption(InputView inputView) {
while (true) {
OutputView.showOptions(title, options);
String optionChosen = inputView.chooseOption();
try {
checkOptions(optionChosen);
return optionChosen;
} catch (ExceptionOptionUnavailable e) {
OutputView.showErrorMessage(e);
}
}
}

public void checkOptions(String input) throws ExceptionOptionUnavailable {
if (!options.containsKey(input)) {
throw new ExceptionOptionUnavailable();
}
}

public void startChosenOption(String option) {
if (option.equals(OPTION_NUM_1)) {
RouteDashboard routeDashboard = new RouteDashboard(inputView);
}

if (option.equals(OPTION_QUIT)) {
power = false;
}
}


}
84 changes: 84 additions & 0 deletions src/main/java/subway/controller/RouteCalculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package subway.controller;

import java.util.List;
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.WeightedMultigraph;
import subway.domain.Line;
import subway.domain.LineRepository;
import subway.domain.Station;
import subway.view.OutputView;

public class RouteCalculator {

Station stationDeparture;
Station stationArrival;
String option;
int totalTime = 0;
int totalDistance = 0;


public RouteCalculator(Station stationDeparture, Station stationArrival, String option) {
this.stationDeparture = stationDeparture;
this.stationArrival = stationArrival;
this.option = option;
try {
if (option.equals("1")) {
getDijkstraShortestPathByDistance();
return;
}

if (option.equals("2")) {
getDijkstraShortestPathByTime();
return;
}

} catch (NullPointerException e) {
OutputView.showErrorStationUnreachable();
}
}

public void getDijkstraShortestPathByDistance() {
WeightedMultigraph<Station, DefaultWeightedEdge> graph = new WeightedMultigraph(
DefaultWeightedEdge.class);
for (Line line : LineRepository.lines()) {
graph.addVertex(line.getStations().get(0));
for (int i = 1; i < line.getStations().size(); i++) {
graph.addVertex(line.getStations().get(i));
graph.setEdgeWeight(
graph.addEdge(line.getStations().get(i - 1), line.getStations().get(i)),
line.getDistances().get(i - 1));
}
}
calculateShortestPath(graph);
}

public void getDijkstraShortestPathByTime() {
WeightedMultigraph<Station, DefaultWeightedEdge> graph = new WeightedMultigraph(
DefaultWeightedEdge.class);
for (Line line : LineRepository.lines()) {
graph.addVertex(line.getStations().get(0));
for (int i = 1; i < line.getStations().size(); i++) {
graph.addVertex(line.getStations().get(i));
graph.setEdgeWeight(
graph.addEdge(line.getStations().get(i - 1), line.getStations().get(i)),
line.getTimes().get(i - 1));
}
}
calculateShortestPath(graph);
}


public void calculateShortestPath(WeightedMultigraph graph) {
DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(graph);
List<Station> shortestPath = dijkstraShortestPath.getPath(stationDeparture, stationArrival)
.getVertexList();

totalTime = (int) dijkstraShortestPath.getPathWeight(stationDeparture, stationArrival);
OutputView.showResult(shortestPath, totalDistance, totalTime);

}



}
Loading