Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
bafc16a
docs(README.md): docs/README.md에 기능 구현 목록 작성
xrabcde Dec 19, 2020
5bae5d2
feat(Line): 노선의 역이름, 거리, 소요시간을 저장할 리스트들 선언 및 생성함수 구현
xrabcde Dec 19, 2020
3ea7aa5
feat(LineRepository): 노선이름, 역이름, 거리, 소요시간을 입력받아 노선을 생성하는 addLine 메소드 구현
xrabcde Dec 19, 2020
2dd8462
feat(Init, Application): 프로그램 시작 시 사전 등록 정보로 초기화 구현
xrabcde Dec 19, 2020
39f1c74
refactor: 초기화 클래스 Init의 상수 리팩토링
xrabcde Dec 19, 2020
965a1b5
feat(Constants): 메인 메뉴와 서브메뉴에 해당하는 상수 추가
xrabcde Dec 19, 2020
e9799d0
feat(View): 메인화면 출력과 프로그램 종료문구 출력해주는 View 클래스 구현
xrabcde Dec 19, 2020
a90fff3
feat(InputView): 기능 입력에 사용할 InputView 구현
xrabcde Dec 19, 2020
f26b9fa
feat(Errors, ErrorMessage): 입력값 검증을 위한 Errors와 에러메시지 출력을 위한 view/Erro…
xrabcde Dec 19, 2020
3bb0c76
feat(Application): 메인화면 기능 목록과 입력 안내 문구 출력, 메인 기능 입력 구현
xrabcde Dec 19, 2020
a0f465a
feat(View): 경로 조회 목록을 출력해주는 showPathMenu 구현
xrabcde Dec 19, 2020
5d5b723
feat(PathManage): 경로 조회 메뉴를 관리하는 PathManage 클래스 구현, 원하는 조회기준 입력 및 예외처…
xrabcde Dec 19, 2020
5dd65c7
feat(Application): 원하는 서브 메뉴 입력 및 예외처리 구현
xrabcde Dec 19, 2020
7197e11
docs(README.md): README 예외처리 수정
xrabcde Dec 19, 2020
c8330d6
feat(StationRepository): 등록된 역인지 검증하기 위해 isExist 메소드 구현
xrabcde Dec 19, 2020
f8c84c7
feat(InputView): 입력값 검증 함수를 반복문에서 재귀함수로 수정, 출발/도착역 입력받는 메소드 구현
xrabcde Dec 19, 2020
ecd6d56
feat(PathManage, Constants, Errors): 최단 경로 조희를 위한 출발역, 도착역 입력 구현, 동일 …
xrabcde Dec 19, 2020
bffcb3e
docs(README.md): README 예외처리 수정
xrabcde Dec 19, 2020
6cc3169
feat(Line): 해당 노선의 역을 순서대로 출력해주는 displayLine 메소드 구현
xrabcde Dec 19, 2020
b09fd13
feat(View): 최단경로 조회 결과를 출력해주는 displayPath 구현
xrabcde Dec 19, 2020
dfb3d8f
docs(README.md): README 불필요한 부분 삭제
xrabcde Dec 19, 2020
714da4f
feat(Init): 소요 시간과 거리에 대한 다익스트라 graph 초기설정에 추가
xrabcde Dec 19, 2020
724ca88
feat(Line, LineRepository): 필요없는 변수들 삭제
xrabcde Dec 19, 2020
6f3378c
feat(JGraphtTest): 최단 경로의 weight 출력 테스트
xrabcde Dec 19, 2020
403b3ce
fix(InputView): 출발역 도착역 입력받는 메소드 수정
xrabcde Dec 19, 2020
24ce8f6
fix(View): 조회 결과 출력 메소드 수정
xrabcde Dec 19, 2020
f147b79
feat(PathManage): 최단 경로 출력 메소드 구현
xrabcde Dec 19, 2020
cabce1c
feat(ErrorMessage): 에러 메시지 추가
xrabcde Dec 19, 2020
fdccf53
fix(Init): 잘못 입력한 가중치값 수정
xrabcde Dec 19, 2020
40896b9
refactor: 불필요한 코드 삭제 및 리팩토링
xrabcde Dec 19, 2020
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
34 changes: 34 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 미션 - 지하철 노선도 경로 조회 미션 🚇

### 💻 기능 구현 목록

- 프로그램 시작 시, 사전 등록정보로 역, 노선, 구간정보 설정
- `조건` 거리와 소요 시간은 Integer, 단위는 km와 분
- 메인화면 기능 목록(1, Q)과 입력 안내 문구 출력
- 원하는 메인 메뉴 입력
- `예외` (1, Q) 외에 다른 값을 입력한 경우
- `처리` 에러 문구([ERROR]) 출력 후 다시 입력

#### 1 경로 조회
- 경로 조회 기능 목록(1, 2, B)과 입력 안내 문구 출력
- 원하는 서브 메뉴 입력
- `예외` (1, 2, B) 외에 다른 값을 입력한 경우
- `처리` 에러 문구([ERROR]) 출력 후 다시 입력
- 출발역 입력 안내 문구 출력 및 출발역 입력
- `예외` 등록되지 않은 역인 경우
- `처리` 에러 문구([ERROR]) 출력 후 다시 입력
- 도착역 입력 안내 문구 출력 및 도착역 입력
- `예외` 등록되지 않은 역인 경우
- `처리` 에러 문구([ERROR]) 출력 후 다시 입력
- `예외` 출발역과 도착역이 같은 경우
- `예외` 출발역과 도착역이 연결되어 있지 않은 경우
- `처리` 에러 문구([ERROR]) 출력 후 다시 입력
- 경로 조회
- `기준1` 최단거리
- `기준2` 최소시간
- 조회 결과 출력
- `조건` 총 거리, 총 소요시간 함께 출력
- 출력 후 메인화면으로 돌아감

#### Q 종료
- 프로그램 종료
20 changes: 19 additions & 1 deletion src/main/java/subway/Application.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
package subway;

import subway.domain.*;
import subway.view.*;

import java.util.Scanner;

public class Application {
public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
// TODO: 프로그램 구현
Init.initialize();
startProgram(scanner);
}

public static void startProgram(Scanner kbd) {
View.showMainMenu();
String mainInput = InputView.inputFunction(kbd, Constants.MAIN_FUNCTIONS);
goSubMenu(mainInput, kbd);
}

public static void goSubMenu(String input, Scanner kbd) {
System.out.println();
if (input.equals(Constants.FIND_PATH))
PathManage.managePath(kbd);
if (input.equalsIgnoreCase(Constants.FINISH_PROGRAM))
View.finishProgram();
}
}
60 changes: 60 additions & 0 deletions src/main/java/subway/PathManage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package subway;

import subway.domain.*;
import subway.view.*;

import java.util.List;
import java.util.Scanner;

import static subway.Application.startProgram;

public class PathManage {
public static void managePath(Scanner kbd) {
View.showPathMenu();
String input = InputView.inputFunction(kbd, Constants.SUB_FUNCTIONS);
if (input.equals(Constants.MIN_DISTANCE))
findMinDistance(kbd);
if (input.equals(Constants.MIN_TIME))
findMinTime(kbd);
if (input.equals(Constants.GO_BACK_MENU))
startProgram(kbd);
}

public static void findMinDistance(Scanner kbd) {
try {
String[] stations = InputView.inputSrcDest(kbd);
List<String> shortestPath = Init.dijkstraDistance.getPath(stations[0], stations[1]).getVertexList();
showMinPath(Constants.PATH_DISTANCE, shortestPath, getMinValue(stations));
startProgram(kbd);
} catch (Exception e) {
startProgram(kbd);
}
}

public static void findMinTime(Scanner kbd) {
try {
String[] stations = InputView.inputSrcDest(kbd);
List<String> shortestPath = Init.dijkstraTime.getPath(stations[0], stations[1]).getVertexList();
showMinPath(Constants.PATH_TIME, shortestPath, getMinValue(stations));
startProgram(kbd);
} catch (Exception e) {
startProgram(kbd);
}
}

public static void showMinPath(String name, List<String> path, int[] values) {
Line minPath = new Line(name);
LineRepository.addLine(minPath, path);
View.displayPath(minPath, values[0], values[1]);
LineRepository.deleteLineByName(name);
}

public static int[] getMinValue(String[] stations) {
double time = Init.dijkstraTime.getPath(stations[0], stations[1]).getWeight();
double distance = Init.dijkstraDistance.getPath(stations[0], stations[1]).getWeight();
int[] values = new int[2];
values[0] = (int) Math.round(time);
values[1] = (int) Math.round(distance);
return values;
}
}
29 changes: 29 additions & 0 deletions src/main/java/subway/domain/Constants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package subway.domain;

import java.util.Arrays;
import java.util.List;

public class Constants {
public static final List<String> STATIONS = Arrays.asList("교대역", "강남역", "역삼역", "남부터미널역", "양재역", "양재시민의숲역", "매봉역");
public static final String LINE_2 = "2호선";
public static final List<String> LINE_2_STATIONS = Arrays.asList("교대역", "강남역", "역삼역");
public static final String LINE_3 = "3호선";
public static final List<String> LINE_3_STATIONS = Arrays.asList("교대역", "남부터미널역", "양재역", "매봉역");
public static final String LINE_SINBUNDANG = "신분당선";
public static final List<String> LINE_SINBUNDANG_STATIONS = Arrays.asList("강남역", "양재역", "양재시민의숲역");
public static final String PATH_DISTANCE = "DISTANCE";
public static final String PATH_TIME = "TIME";

public static final int FUNCTION_INPUT_ERROR = 0;
public static final int NO_SUCH_NAME_ERROR = 1;
public static final int SAME_NAME_ERROR = 2;
public static final int UNKNOWN_ERROR = 3;

public static final String FIND_PATH = "1";
public static final String FINISH_PROGRAM = "Q";
public static final List<String> MAIN_FUNCTIONS = Arrays.asList(FIND_PATH, FINISH_PROGRAM);
public static final String MIN_DISTANCE = "1";
public static final String MIN_TIME = "2";
public static final String GO_BACK_MENU = "B";
public static final List<String> SUB_FUNCTIONS = Arrays.asList(MIN_DISTANCE, MIN_TIME, GO_BACK_MENU);
}
28 changes: 28 additions & 0 deletions src/main/java/subway/domain/Errors.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package subway.domain;

import subway.view.ErrorMessage;

import java.util.List;

public class Errors {
public static void checkInput(String input, List<String> functions) {
if (!functions.contains(input)) {
ErrorMessage.displayErrorMessage(Constants.FUNCTION_INPUT_ERROR);
throw new IllegalArgumentException();
}
}

public static void checkExistStation(String name) {
if (!StationRepository.isExist(name)) {
ErrorMessage.displayErrorMessage(Constants.NO_SUCH_NAME_ERROR);
throw new IllegalArgumentException();
}
}

public static void checkSameName(String firstName, String lastName) {
if (firstName.equals(lastName)) {
ErrorMessage.displayErrorMessage(Constants.SAME_NAME_ERROR);
throw new IllegalArgumentException();
}
}
}
77 changes: 77 additions & 0 deletions src/main/java/subway/domain/Init.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package subway.domain;

import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.WeightedMultigraph;


public class Init {
public static DijkstraShortestPath dijkstraDistance;
public static DijkstraShortestPath dijkstraTime;

public static void initialize() {
initializeStation();
initializeLine();
initializeTimeGraph();
dijkstraDistance = initializeDistanceGraph();
dijkstraTime = initializeTimeGraph();
}

public static void initializeStation() {
for (String name : Constants.STATIONS)
StationRepository.addStation(new Station(name));
}

public static void initializeLine() {
Line line2 = new Line(Constants.LINE_2);
LineRepository.addLine(line2, Constants.LINE_2_STATIONS);
Line line3 = new Line(Constants.LINE_3);
LineRepository.addLine(line3, Constants.LINE_3_STATIONS);
Line lineSinbundang = new Line(Constants.LINE_SINBUNDANG);
LineRepository.addLine(lineSinbundang, Constants.LINE_SINBUNDANG_STATIONS);
}

public static DijkstraShortestPath initializeDistanceGraph() {
WeightedMultigraph<String, DefaultWeightedEdge> graph = initializeGraph();
int edges = 0;
for (Line line : LineRepository.lines())
edges += line.getSize() - 1;
for (int i = 0; i < edges; i++) {
graph.setEdgeWeight(graph.addEdge("교대역", "강남역"), 2);
graph.setEdgeWeight(graph.addEdge("강남역", "역삼역"), 2);
graph.setEdgeWeight(graph.addEdge("교대역", "남부터미널역"), 3);
graph.setEdgeWeight(graph.addEdge("남부터미널역", "양재역"), 6);
graph.setEdgeWeight(graph.addEdge("양재역", "매봉역"), 1);
graph.setEdgeWeight(graph.addEdge("강남역", "양재역"), 2);
graph.setEdgeWeight(graph.addEdge("양재역", "양재시민의숲역"), 10);
}
DijkstraShortestPath dijkstraDistance = new DijkstraShortestPath(graph);
return dijkstraDistance;
}

public static DijkstraShortestPath initializeTimeGraph() {
WeightedMultigraph<String, DefaultWeightedEdge> graph = initializeGraph();
int edges = 0;
for (Line line : LineRepository.lines())
edges += line.getSize() - 1;
for (int i = 0; i < edges; i++) {
graph.setEdgeWeight(graph.addEdge("교대역", "강남역"), 3);
graph.setEdgeWeight(graph.addEdge("강남역", "역삼역"), 3);
graph.setEdgeWeight(graph.addEdge("교대역", "남부터미널역"), 2);
graph.setEdgeWeight(graph.addEdge("남부터미널역", "양재역"), 5);
graph.setEdgeWeight(graph.addEdge("양재역", "매봉역"), 1);
graph.setEdgeWeight(graph.addEdge("강남역", "양재역"), 8);
graph.setEdgeWeight(graph.addEdge("양재역", "양재시민의숲역"), 3);
}
DijkstraShortestPath dijkstraTime = new DijkstraShortestPath(graph);
return dijkstraTime;
}

public static WeightedMultigraph<String, DefaultWeightedEdge> initializeGraph() {
WeightedMultigraph<String, DefaultWeightedEdge> graph
= new WeightedMultigraph(DefaultWeightedEdge.class);
for (String name : Constants.STATIONS)
graph.addVertex(name);
return graph;
}
}
18 changes: 17 additions & 1 deletion src/main/java/subway/domain/Line.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package subway.domain;

import java.util.ArrayList;
import java.util.List;

public class Line {
private String name;
private List<String> stationNames = new ArrayList<>();

public Line(String name) {
this.name = name;
Expand All @@ -11,5 +15,17 @@ public String getName() {
return name;
}

// 추가 기능 구현
public void addStation(int index, String name) {
stationNames.add(index-1, name);
}

public void displayLine() {
for (String station : stationNames)
System.out.println("[INFO] " + station);
System.out.println();
}

public int getSize() {
return stationNames.size();
}
}
4 changes: 3 additions & 1 deletion src/main/java/subway/domain/LineRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ public static List<Line> lines() {
return Collections.unmodifiableList(lines);
}

public static void addLine(Line line) {
public static void addLine(Line line, List<String> names) {
for (int i = 1; i <= names.size(); i++)
line.addStation(i, names.get(i-1));
lines.add(line);
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/subway/domain/StationRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ public static boolean deleteStation(String name) {
public static void deleteAll() {
stations.clear();
}

public static boolean isExist(String name) {
return stations.stream().map(Station::getName).anyMatch(x -> x.equals(name));
}
}
16 changes: 16 additions & 0 deletions src/main/java/subway/view/ErrorMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package subway.view;

import subway.domain.Constants;

public class ErrorMessage {
public static void displayErrorMessage(int errorCase) {
if (errorCase == Constants.FUNCTION_INPUT_ERROR)
System.out.println("[ERROR] 선택할 수 없는 기능입니다.");
if (errorCase == Constants.NO_SUCH_NAME_ERROR)
System.out.println("[ERROR] 등록되지 않은 역 이름입니다.");
if (errorCase == Constants.SAME_NAME_ERROR)
System.out.println("[ERROR] 출발역과 도착역은 같을 수 없습니다.");
if (errorCase == Constants.UNKNOWN_ERROR)
System.out.println("[ERROR] 알 수 없는 오류가 발생했습니다.");
}
}
36 changes: 36 additions & 0 deletions src/main/java/subway/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package subway.view;

import subway.domain.Errors;

import java.util.List;
import java.util.Scanner;

public class InputView {
public static String inputFunction(Scanner kbd, List<String> functions) {
String input = "0";
try {
System.out.println("\n## 원하는 기능을 선택하세요.");
input = kbd.nextLine();
Errors.checkInput(input, functions);
} catch (Exception e) {
inputFunction(kbd, functions);
}
return input;
}

public static String[] inputSrcDest(Scanner kbd) {
String[] stations = new String[2];
try {
System.out.println("\n## 출발역을 입력하세요.");
stations[0] = kbd.nextLine();
Errors.checkExistStation(stations[0]);
System.out.println("\n## 도착역을 입력하세요.");
stations[1] = kbd.nextLine();
Errors.checkExistStation(stations[1]);
Errors.checkSameName(stations[0], stations[1]);
} catch (Exception e) {
inputSrcDest(kbd);
}
return stations;
}
}
Loading