diff --git a/README.md b/README.md index d6299154c..1654bf6e1 100644 --- a/README.md +++ b/README.md @@ -3,251 +3,14 @@
-## ๐Ÿš€ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ - -> ํ”„๋ฆฌ์ฝ”์Šค 3์ฃผ์ฐจ ๋ฏธ์…˜์—์„œ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•ด๋„ ๋ฌด๊ด€ํ•˜๋‹ค. - -### ์ดˆ๊ธฐ ์„ค์ • -- ํ”„๋กœ๊ทธ๋žจ ์‹œ์ž‘ ์‹œ ์—ญ, ๋…ธ์„ , ๊ตฌ๊ฐ„ ์ •๋ณด๋ฅผ ์ดˆ๊ธฐ ์„ค์ • ํ•ด์•ผ ํ•œ๋‹ค. -- ๊ฑฐ๋ฆฌ์™€ ์†Œ์š” ์‹œ๊ฐ„์€ ์–‘์˜ ์ •์ˆ˜์ด๋ฉฐ ๋‹จ์œ„๋Š” km์™€ ๋ถ„์„ ์˜๋ฏธํ•œ๋‹ค. -- ์•„๋ž˜์˜ ์‚ฌ์ „ ๋“ฑ๋ก ์ •๋ณด๋กœ ๋ฐ˜๋“œ์‹œ ์ดˆ๊ธฐ ์„ค์ •์„ ํ•œ๋‹ค. - -``` - 1. ์ง€ํ•˜์ฒ ์—ญ์œผ๋กœ ๊ต๋Œ€์—ญ, ๊ฐ•๋‚จ์—ญ, ์—ญ์‚ผ์—ญ, ๋‚จ๋ถ€ํ„ฐ๋ฏธ๋„์—ญ, ์–‘์žฌ์—ญ, ์–‘์žฌ์‹œ๋ฏผ์˜์ˆฒ์—ญ, ๋งค๋ด‰์—ญ์ด ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค. - 2. ์ง€ํ•˜์ฒ  ๋…ธ์„ ์œผ๋กœ 2ํ˜ธ์„ , 3ํ˜ธ์„ , ์‹ ๋ถ„๋‹น์„ ์ด ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค. - 3. ๋…ธ์„ ์— ์—ญ์ด ์•„๋ž˜์™€ ๊ฐ™์ด ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค.(์™ผ์ชฝ ๋์ด ์ƒํ–‰ ์ข…์ ) - - 2ํ˜ธ์„ : ๊ต๋Œ€์—ญ - ( 2km / 3๋ถ„ ) - ๊ฐ•๋‚จ์—ญ - ( 2km / 3๋ถ„ ) - ์—ญ์‚ผ์—ญ - - 3ํ˜ธ์„ : ๊ต๋Œ€์—ญ - ( 3km / 2๋ถ„ ) - ๋‚จ๋ถ€ํ„ฐ๋ฏธ๋„์—ญ - ( 6km / 5๋ถ„ ) - ์–‘์žฌ์—ญ - ( 1km / 1๋ถ„ ) - ๋งค๋ด‰์—ญ - - ์‹ ๋ถ„๋‹น์„ : ๊ฐ•๋‚จ์—ญ - ( 2km / 8๋ถ„ ) - ์–‘์žฌ์—ญ - ( 10km / 3๋ถ„ ) - ์–‘์žฌ์‹œ๋ฏผ์˜์ˆฒ์—ญ - ``` - -### ๊ฒฝ๋กœ ์กฐํšŒ ๊ธฐ๋Šฅ -- ์ถœ๋ฐœ์—ญ๊ณผ ๋„์ฐฉ์—ญ์„ ์ž…๋ ฅ๋ฐ›์•„ ๊ฒฝ๋กœ๋ฅผ ์กฐํšŒํ•œ๋‹ค. -- ๊ฒฝ๋กœ ์กฐํšŒ ์‹œ ์ด ๊ฑฐ๋ฆฌ, ์ด ์†Œ์š” ์‹œ๊ฐ„๋„ ํ•จ๊ป˜ ์ถœ๋ ฅํ•œ๋‹ค. -- ๊ฒฝ๋กœ ์กฐํšŒ ๊ธฐ์ค€์€ `์ตœ๋‹จ ๊ฑฐ๋ฆฌ` `์ตœ์†Œ ์‹œ๊ฐ„`์ด ์žˆ๋‹ค. - -### ์˜ˆ์™ธ ์ฒ˜๋ฆฌ -- ๊ฒฝ๋กœ ์กฐํšŒ ์‹œ ์ถœ๋ฐœ์—ญ๊ณผ ๋„์ฐฉ์—ญ์ด ๊ฐ™์œผ๋ฉด ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. -- ๊ฒฝ๋กœ ์กฐํšŒ ์‹œ ์ถœ๋ฐœ์—ญ๊ณผ ๋„์ฐฉ์—ญ์ด ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. -- ๊ทธ ์™ธ ์ •์ƒ์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์ด ์ˆ˜ํ–‰๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. - -
- -## โœ๐Ÿป ์ž…์ถœ๋ ฅ ์š”๊ตฌ์‚ฌํ•ญ -- `ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹คํ–‰ ๊ฒฐ๊ณผ ์˜ˆ์‹œ`์™€ ๋™์ผํ•˜๊ฒŒ ์ž…์ถœ๋ ฅ์„ ๊ตฌํ˜„ํ•œ๋‹ค. -- ๊ธฐ๋Œ€ํ•˜๋Š” ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š” `[INFO]`๋ฅผ ๋ถ™์—ฌ์„œ ์ถœ๋ ฅํ•œ๋‹ค. ์ถœ๋ ฅ๊ฐ’์˜ ํ˜•์‹์€ ์˜ˆ์‹œ์™€ ๋™์ผํ•˜๊ฒŒ ํ•œ๋‹ค. -- ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ `[ERROR]`๋ฅผ ๋ถ™์—ฌ์„œ ์ถœ๋ ฅํ•œ๋‹ค. ์—๋Ÿฌ์˜ ๋ฌธ๊ตฌ๋Š” ์ž์œ ๋กญ๊ฒŒ ์ž‘์„ฑํ•œ๋‹ค. - -### ๐Ÿ’ป ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹คํ–‰ ๊ฒฐ๊ณผ ์˜ˆ์‹œ -#### ๊ฒฝ๋กœ ์กฐํšŒ -``` -## ๋ฉ”์ธ ํ™”๋ฉด -1. ๊ฒฝ๋กœ ์กฐํšŒ -Q. ์ข…๋ฃŒ - -## ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์„ธ์š”. -1 - -## ๊ฒฝ๋กœ ๊ธฐ์ค€ -1. ์ตœ๋‹จ ๊ฑฐ๋ฆฌ -2. ์ตœ์†Œ ์‹œ๊ฐ„ -B. ๋Œ์•„๊ฐ€๊ธฐ - -## ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์„ธ์š”. -1 - -## ์ถœ๋ฐœ์—ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”. -๊ต๋Œ€์—ญ - -## ๋„์ฐฉ์—ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”. -์–‘์žฌ์—ญ - -## ์กฐํšŒ ๊ฒฐ๊ณผ -[INFO] --- -[INFO] ์ด ๊ฑฐ๋ฆฌ: 6km -[INFO] ์ด ์†Œ์š” ์‹œ๊ฐ„: 14๋ถ„ -[INFO] --- -[INFO] ๊ต๋Œ€์—ญ -[INFO] ๊ฐ•๋‚จ์—ญ -[INFO] ์–‘์žฌ์—ญ - -## ๋ฉ”์ธ ํ™”๋ฉด -1. ๊ฒฝ๋กœ ์กฐํšŒ -Q. ์ข…๋ฃŒ - -... -``` - -#### ์—๋Ÿฌ ์ถœ๋ ฅ ์˜ˆ์‹œ - -``` -## ๋ฉ”์ธ ํ™”๋ฉด -1. ๊ฒฝ๋กœ ์กฐํšŒ -Q. ์ข…๋ฃŒ - -## ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์„ธ์š”. -1 - -## ๊ฒฝ๋กœ ๊ธฐ์ค€ -1. ์ตœ๋‹จ ๊ฑฐ๋ฆฌ -2. ์ตœ์†Œ ์‹œ๊ฐ„ -B. ๋Œ์•„๊ฐ€๊ธฐ - -## ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์„ธ์š”. -1 - -## ์ถœ๋ฐœ์—ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”. -๊ฐ•๋‚จ์—ญ - -## ๋„์ฐฉ์—ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”. -๊ฐ•๋‚จ์—ญ - -[ERROR] ์ถœ๋ฐœ์—ญ๊ณผ ๋„์ฐฉ์—ญ์ด ๋™์ผํ•ฉ๋‹ˆ๋‹ค. - -## ๊ฒฝ๋กœ ๊ธฐ์ค€ -1. ์ตœ๋‹จ ๊ฑฐ๋ฆฌ -2. ์ตœ์†Œ ์‹œ๊ฐ„ -B. ๋Œ์•„๊ฐ€๊ธฐ - -## ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์„ธ์š”. - -... - -``` - -
- -## ๐ŸŽฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ -- ์ž๋ฐ” ์ฝ”๋“œ ์ปจ๋ฒค์…˜์„ ์ง€ํ‚ค๋ฉด์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•œ๋‹ค. - - ๊ธฐ๋ณธ์ ์œผ๋กœ [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)์„ ์›์น™์œผ๋กœ ํ•œ๋‹ค. - - ๋‹จ, ๋“ค์—ฌ์“ฐ๊ธฐ๋Š” '2 spaces'๊ฐ€ ์•„๋‹Œ '4 spaces'๋กœ ํ•œ๋‹ค. -- indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. 2๊นŒ์ง€๋งŒ ํ—ˆ์šฉํ•œ๋‹ค. - - ์˜ˆ๋ฅผ ๋“ค์–ด while๋ฌธ ์•ˆ์— if๋ฌธ์ด ์žˆ์œผ๋ฉด ๋“ค์—ฌ์“ฐ๊ธฐ๋Š” 2์ด๋‹ค. - - ํžŒํŠธ: indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ ์ค„์ด๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์†Œ๋“œ)๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฉด ๋œ๋‹ค. -- 3ํ•ญ ์—ฐ์‚ฐ์ž๋ฅผ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. -- ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์†Œ๋“œ)์˜ ๊ธธ์ด๊ฐ€ 15๋ผ์ธ์„ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. - - ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์†Œ๋“œ)๊ฐ€ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ์ž˜ ํ•˜๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. -- else ์˜ˆ์•ฝ์–ด๋ฅผ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. - - ํžŒํŠธ: if ์กฐ๊ฑด์ ˆ์—์„œ ๊ฐ’์„ returnํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด else๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. - - else๋ฅผ ์“ฐ์ง€ ๋ง๋ผ๊ณ  ํ•˜๋‹ˆ switch/case๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ switch/case๋„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. -- ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ์—์„œ ๋ณ„๋„๋กœ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€ ์•ˆ๋‚ด๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ํŒŒ์ผ ์ˆ˜์ •๊ณผ ํŒจํ‚ค์ง€ ์ด๋™์„ ์ž์œ ๋กญ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. -- ์˜ˆ์™ธ ์ƒํ™ฉ ์‹œ ์—๋Ÿฌ ๋ฌธ๊ตฌ๋ฅผ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค. ๋‹จ, ์—๋Ÿฌ ๋ฌธ๊ตฌ๋Š” `[ERROR]` ๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค. - -### ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ - Application -- Application ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. -- Application์˜ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ๋Š” ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค. -- Application ํด๋ž˜์Šค์— ์žˆ๋Š” Scanner๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ณ„๋„์˜ Scanner ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. -```java -public class Application { - public static void main(String[] args) { - final Scanner scanner = new Scanner(System.in); - ... - } -} -``` - -### ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ - Station, Line -- Station, Line ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ง€ํ•˜์ฒ ์—ญ๊ณผ ๋…ธ์„ ์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. -- ์ œ๊ณตํ•˜๋Š” ๊ฐ ํด๋ž˜์Šค์˜ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋‹ค. -- ํ•„๋“œ(์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜)์ธ name์˜ ์ ‘๊ทผ ์ œ์–ด์ž private์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค. -- ๊ฐ€๋Šฅํ•˜๋ฉด setter ๋ฉ”์†Œ๋“œ(ex. setXXX)๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  ๊ตฌํ˜„ํ•œ๋‹ค. - -```java -public class Station { - private String name; - - public Station(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - // ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ -} - -``` - -### ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ - StationRepository, LineRepository -- Station๊ณผ Line์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” StationRepository, LineRepository๋ฅผ ์ œ๊ณตํ•œ๋‹ค. -- ํ•„์š” ์‹œ StationRepository, LineRepository ์ด ์™ธ ์ถ”๊ฐ€๋กœ Repository๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. -- ์ถ”๊ฐ€๋กœ ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด์— ๋Œ€ํ•ด์„œ XXXRepository ๋„ค์ด๋ฐ์œผ๋กœ ์ €์žฅ ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. -- ๊ฐ์ฒด๋“ค์˜ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ XXXRepository ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด ์ €์žฅ ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. -- ์ž‘์„ฑ๋œ ๋ฉ”์„œ๋“œ๋Š” ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๊ณ , ํ•„์š”์— ๋”ฐ๋ผ ๋ฉ”์„œ๋“œ๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค. - -```java -public class StationRepository { - private static final List stations = new ArrayList<>(); - - public static List stations() { - return Collections.unmodifiableList(stations); - } - - public static void addStation(Station station) { - stations.add(station); - } - - public static boolean deleteStation(String name) { - return stations.removeIf(station -> Objects.equals(station.getName(), name)); - } - - public static void deleteAll() { - stations.clear(); - } -} -``` - -
- -## โ—๏ธํžŒํŠธ -### ์ตœ๋‹จ ๊ฒฝ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ -- jgrapht ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๊ฐ„ํŽธํ•˜๊ฒŒ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Œ -- Dijkstra ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ฐ˜๋“œ์‹œ ์ดํ•ดํ•  ํ•„์š”๋Š” ์—†๊ณ  ๋ฏธ์…˜์— ์ ์šฉํ•  ์ •๋„๋กœ๋งŒ ์ดํ•ดํ•˜๋ฉด ๋จ -- JGraphtTest ํด๋ž˜์Šค์˜ ํ…Œ์ŠคํŠธ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฏธ์…˜์— ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ธฐ๋Šฅ์„ ํ•™์Šตํ•  ์ˆ˜ ์žˆ์Œ -- ์ •์ (vertex)๊ณผ ๊ฐ„์„ (edge), ๊ทธ๋ฆฌ๊ณ  ๊ฐ€์ค‘์น˜ ๊ฐœ๋…์„ ์ด์šฉ - - ์ •์ : ์ง€ํ•˜์ฒ ์—ญ - - ๊ฐ„์„ : ์ง€ํ•˜์ฒ ์—ญ ์—ฐ๊ฒฐ์ •๋ณด - - ๊ฐ€์ค‘์น˜: ๊ฑฐ๋ฆฌ or ์†Œ์š” ์‹œ๊ฐ„ -- ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๊ธฐ์ค€ ์กฐํšŒ ์‹œ ๊ฐ€์ค‘์น˜๋ฅผ ๊ฑฐ๋ฆฌ๋กœ ์„ค์ • - -```java -@Test -public void getDijkstraShortestPath() { - WeightedMultigraph graph - = new WeightedMultigraph(DefaultWeightedEdge.class); - graph.addVertex("v1"); - graph.addVertex("v2"); - graph.addVertex("v3"); - graph.setEdgeWeight(graph.addEdge("v1", "v2"), 2); - graph.setEdgeWeight(graph.addEdge("v2", "v3"), 2); - graph.setEdgeWeight(graph.addEdge("v1", "v3"), 100); - - DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(graph); - List shortestPath = dijkstraShortestPath.getPath("v3", "v1").getVertexList(); - - assertThat(shortestPath.size()).isEqualTo(3); -} -``` - -#### ํ…Œ์ŠคํŠธ ์„ค๋ช… - - - -- ์—ญ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ V1->V3 ๊ฒฝ๋กœ๊ฐ€ ์ตœ๋‹จ ๊ฒฝ๋กœ -- ์—ญ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ ๋ คํ•  ๊ฒฝ์šฐ V1->V3 ๊ฒฝ๋กœ์˜ ๊ฑฐ๋ฆฌ๋Š” 100km, V1->V2->V3 ๊ฒฝ๋กœ์˜ ๊ฑฐ๋ฆฌ๋Š” 4km์ด๋ฏ€๋กœ ์ตœ๋‹จ ๊ฒฝ๋กœ๋Š” V1->V2->V3 - -
- -## ๐Ÿ“ˆ ์ง„ํ–‰ ์š”๊ตฌ์‚ฌํ•ญ -- ๋ฏธ์…˜์€ [java-subway-path-precourse ์ €์žฅ์†Œ](https://github.com/woowacourse/java-subway-path-precourse) ๋ฅผ fork/cloneํ•ด ์‹œ์ž‘ํ•œ๋‹ค. -- ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์— java-subway-path-precourse/docs/README.md ํŒŒ์ผ์— ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ์ •๋ฆฌํ•ด ์ถ”๊ฐ€ํ•œ๋‹ค. -- git์˜ commit ๋‹จ์œ„๋Š” ์•ž ๋‹จ๊ณ„์—์„œ README.md ํŒŒ์ผ์— ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก ๋‹จ์œ„๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค. - - [AngularJS Commit Message Conventions](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) ์ฐธ๊ณ ํ•ด commit log๋ฅผ ๋‚จ๊ธด๋‹ค. -- [ํ”„๋ฆฌ์ฝ”์Šค ๊ณผ์ œ ์ œ์ถœ ๋ฌธ์„œ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) ์ ˆ์ฐจ๋ฅผ ๋”ฐ๋ผ ๋ฏธ์…˜์„ ์ œ์ถœํ•œ๋‹ค. - - [ํ”„๋ฆฌ์ฝ”์Šค ๊ณผ์ œ FAQ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse/faq) ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. -
- -## ๐Ÿ“ License - -This project is [MIT](https://github.com/woowacourse/java-subway-path-precourse/blob/master/LICENSE.md) licensed. +## ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก + +- ์—ญ, ๋…ธ์„ , ๊ตฌ๊ฐ„ ์ •๋ณด ์ดˆ๊ธฐํ™”(๋‹จ์œ„ km, ๋ถ„) + - ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋ฐ›๋Š” ๋ถ€๋ถ„์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์ง€ ์•Š์•˜๋‹ค. +- ๋ฉ”์ธ ํ™”๋ฉด์—์„œ ๊ธฐ๋Šฅ ์„ ํƒ + - ์˜ˆ์™ธ ์ฒ˜๋ฆฌ : ์„ ํƒ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ ๋ฒˆํ˜ธ ์ž…๋ ฅ +- ์ถœ๋ฐœ์—ญ, ๋„์ฐฉ์—ญ ์ž…๋ ฅ๋ฐ›๊ธฐ + - ์˜ˆ์™ธ ์ฒ˜๋ฆฌ : ์—ญ ๋ชฉ๋ก์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ž…๋ ฅ, ๊ฐ™์€ ์ด๋ฆ„์˜ ์—ญ์„ ๋ฐ›์„ ๊ฒฝ์šฐ +- ๊ฒฝ๋กœ ์กฐํšŒ ์‹œ ๊ฑฐ๋ฆฌ, ์‹œ๊ฐ„ ๊ธฐ์ค€ +- ์ด ๊ฑฐ๋ฆฌ, ์ด ์†Œ์š”์‹œ๊ฐ„, ์ง€๋‚˜์˜จ ๊ตฌ๊ฐ„ ์ถœ๋ ฅ +- ๋‹ค์ต์ŠคํŠธ๋ผ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ฒฝ๋กœ ๊ตฌํ•˜๊ธฐ \ No newline at end of file diff --git a/src/main/java/subway/Application.java b/src/main/java/subway/Application.java index 0bcf786cc..65a95c9a9 100644 --- a/src/main/java/subway/Application.java +++ b/src/main/java/subway/Application.java @@ -6,5 +6,8 @@ public class Application { public static void main(String[] args) { final Scanner scanner = new Scanner(System.in); // TODO: ํ”„๋กœ๊ทธ๋žจ ๊ตฌํ˜„ + User user = new User(scanner); + SubwayManagement subwayManagement = new SubwayManagement(user); + subwayManagement.start(); } } diff --git a/src/main/java/subway/Constants.java b/src/main/java/subway/Constants.java new file mode 100644 index 000000000..fe3b5322c --- /dev/null +++ b/src/main/java/subway/Constants.java @@ -0,0 +1,11 @@ +package subway; + +public class Constants { + public static final String FUNCTION_ONE = "1"; + public static final String FUNCTION_TWO = "2"; + public static final String FUNCTION_Q = "Q"; + public static final String FUNCTION_B = "B"; + public static final String TIME_COST = "TIME"; + public static final String DISTANCE_COST = "DISTANCE"; + public static final int ERROR_CODE = -1; +} diff --git a/src/main/java/subway/FindPath.java b/src/main/java/subway/FindPath.java new file mode 100644 index 000000000..8d318e2ed --- /dev/null +++ b/src/main/java/subway/FindPath.java @@ -0,0 +1,165 @@ +package subway; + +import subway.domain.NodeData; +import subway.domain.Station; +import subway.domain.StationRepository; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.PriorityQueue; +import java.util.Stack; + +public class FindPath { + + private static final int INIT_MIN_VALUE = 0; + private static final int MAX_VALUE = 99999999; + + private static ArrayList> subwayList; + private static int dist[]; + private static boolean visited[]; + private static int parent[]; + private static int stationSize; + private static PriorityQueue q; + + public static void start(String select, String startStation, String arriveStation) { + setBeforeDijkstra(select, startStation); + int minCost = startDijkstra(startStation, arriveStation); + if (minCost == MAX_VALUE) { + throw new IllegalArgumentException("[ERROR] ์„œ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์€ ์—ญ์ž…๋‹ˆ๋‹ค."); + } + String kind = Constants.DISTANCE_COST; + if (select.equals(Constants.FUNCTION_TWO)) { + kind = Constants.TIME_COST; + } + int anotherMinCost = traceMinCost(findNumberByName(startStation), findNumberByName(arriveStation), select); + Stack stack = tracePath(findNumberByName(startStation), findNumberByName(arriveStation)); + PrintScreen.printMinPathStationToArrive(kind, stack, minCost, anotherMinCost); + } + + private static int traceMinCost(int startNumber, int endNumber, String kind) { + if (kind.equals(Constants.FUNCTION_ONE)) { + kind = Constants.TIME_COST; + } + if (kind.equals(Constants.FUNCTION_TWO)) { + kind = Constants.DISTANCE_COST; + } + int minCost = 0; + int cur = endNumber; + + while (cur != startNumber) { + minCost += StationRepository.getCost(findNameByNumber(cur), findNameByNumber(parent[cur]), kind); + cur = parent[cur]; + } + return minCost; + } + + private static Stack tracePath(int startNumber, int endNumber) { + Stack stack = new Stack<>(); + int cur = endNumber; + + while (cur != startNumber) { + stack.push(findNameByNumber(cur)); + cur = parent[cur]; + } + stack.push(findNameByNumber(cur)); + return stack; + } + + //depth 2์ดํ•˜๋กœ ๊ณ ์น˜๊ธฐ, ๋ฉ”์†Œ๋“œ 15์ค„ ์ดํ•˜ + private static int startDijkstra(String startStation, String arriveStation) { + int startNumber = findNumberByName(startStation); + int arriveNumber = findNumberByName(arriveStation); + dist[startNumber] = INIT_MIN_VALUE; + visited[startNumber] = true; + + while (!q.isEmpty()) { + Pair p = q.poll(); + + int start = p.start; + + for (int i = 0; i < subwayList.get(start).size(); i++) { + int end = subwayList.get(start).get(i).end; + int cost = subwayList.get(start).get(i).cost; + if (!visited[end]) { + if (dist[end] > dist[start] + cost) { + dist[end] = dist[start] + cost; + q.add(new Pair(end, 0, dist[end])); + parent[end] = start; + } + } + } + visited[start] = true; + } + + return dist[arriveNumber]; + } + + private static void setBeforeDijkstra(String select, String startStation) { + subwayList = new ArrayList>(); + stationSize = StationRepository.getSize(); + setSubwayList(select); + dist = new int[stationSize]; + visited = new boolean[stationSize]; + parent = new int[stationSize]; + Arrays.fill(dist, MAX_VALUE); + q = new PriorityQueue<>(); + + q.add(new Pair(findNumberByName(startStation), 0, 0)); + } + + private static void setSubwayList(String select) { + for (int i = 0; i < stationSize; i++) { + subwayList.add(new ArrayList()); + } + + for (int i = 0; i < stationSize; i++) { + Station station = StationRepository.stations().get(i); + for (NodeData nodeData : station.getNodeData()) { + int cost = selectDistanceOrTime(select, nodeData); + subwayList.get(i).add(new Pair(findNumberByName(nodeData.getBeforeStation()), findNumberByName(nodeData.getNextStation()), cost)); + } + } + } + + private static String findNameByNumber(int number) { + return StationRepository.stations().get(number).getName(); + } + + private static int findNumberByName(String name) { + for (int i = 0; i < stationSize; i++) { + + if (StationRepository.stations().get(i).getName().equals(name)) { + return i; + } + } + + return Constants.ERROR_CODE; + } + + private static int selectDistanceOrTime(String select, NodeData nodeData) { + if (select.equals(Constants.FUNCTION_ONE)) { + return nodeData.getDistanceCost(); + } + if (select.equals(Constants.FUNCTION_TWO)) { + return nodeData.getTimeCost(); + } + + return Constants.ERROR_CODE; + } + + public static class Pair implements Comparable { + int start, end, cost; + + Pair(int start, int end, int cost) { + this.start = start; + this.end = end; + this.cost = cost; + } + + @Override + public int compareTo(Pair o) { + // TODO Auto-generated method stub + return this.cost - o.cost; + } + } +} diff --git a/src/main/java/subway/InitSetting.java b/src/main/java/subway/InitSetting.java new file mode 100644 index 000000000..88bf4cc43 --- /dev/null +++ b/src/main/java/subway/InitSetting.java @@ -0,0 +1,56 @@ +package subway; + +import subway.domain.Line; +import subway.domain.LineRepository; +import subway.domain.Station; +import subway.domain.StationRepository; + +public class InitSetting { + + private static String[] initStation = {"๊ต๋Œ€์—ญ", "๊ฐ•๋‚จ์—ญ", "์—ญ์‚ผ์—ญ", "๋‚จ๋ถ€ํ„ฐ๋ฏธ๋„์—ญ", "์–‘์žฌ์—ญ", "์–‘์žฌ์‹œ๋ฏผ์˜์ˆฒ์—ญ", "๋งค๋ด‰์—ญ"}; + private static String[] initLine = {"2ํ˜ธ์„ ", "3ํ˜ธ์„ ", "์‹ ๋ถ„๋‹น์„ "}; + private static String[][] initSection = {{"๊ต๋Œ€์—ญ", "๊ฐ•๋‚จ์—ญ", "์—ญ์‚ผ์—ญ"}, {"๊ต๋Œ€์—ญ", "๋‚จ๋ถ€ํ„ฐ๋ฏธ๋„์—ญ", "์–‘์žฌ์—ญ", "๋งค๋ด‰์—ญ"}, {"๊ฐ•๋‚จ์—ญ", "์–‘์žฌ์—ญ", "์–‘์žฌ์‹œ๋ฏผ์˜์ˆฒ์—ญ"}}; + // "km, ๋ถ„" + private static String[][] initCost = {{"2,3", "2,3"}, {"3,2", "6,5", "1,1"}, {"2,8", "10,3"}}; + + + public static void initSetting() { + setInitStation(); + setInitLine(); + setInitSection(); + setInitCost(); + } + + private static void setInitStation() { + for (String name : initStation) { + StationRepository.addStation(new Station(name)); + } + } + + private static void setInitLine() { + for (String name : initLine) { + LineRepository.addLine(new Line(name)); + } + } + + private static void setInitSection() { + for (int i = 0; i < initSection.length; i++) { + for (String name : initSection[i]) { + LineRepository.addSection(i, name); + } + } + } + + private static void setInitCost() { + for (int i = 0; i < initCost.length; i++) { + for (int j = 0; j < initCost[i].length; j++) { + String[] cost = initCost[i][j].split(","); + int distanceCost = Integer.parseInt(cost[0]); + int timeCost = Integer.parseInt(cost[1]); + String curStation = initSection[i][j]; + String nextStation = initSection[i][j + 1]; + StationRepository.setCost(curStation, nextStation, timeCost, distanceCost); + } + } + } +} diff --git a/src/main/java/subway/PrintScreen.java b/src/main/java/subway/PrintScreen.java new file mode 100644 index 000000000..99185332c --- /dev/null +++ b/src/main/java/subway/PrintScreen.java @@ -0,0 +1,52 @@ +package subway; + +import java.util.Stack; + +public class PrintScreen { + + public static void printMain() { + System.out.println("## ๋ฉ”์ธ ํ™”๋ฉด"); + System.out.println("1. ๊ฒฝ๋กœ ์กฐํšŒ"); + System.out.println("Q. ์ข…๋ฃŒ"); + + selectFunction(); + } + + public static void selectFunction() { + System.out.println("\n## ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜์„ธ์š”."); + } + + public static void selectStandard() { + System.out.println("## ๊ฒฝ๋กœ ๊ธฐ์ค€"); + System.out.println("1. ์ตœ๋‹จ ๊ฑฐ๋ฆฌ"); + System.out.println("2. ์ตœ์†Œ ์‹œ๊ฐ„"); + System.out.println("B. ๋Œ์•„๊ฐ€๊ธฐ"); + + selectFunction(); + } + + public static void printInputStartStation() { + System.out.println("## ์ถœ๋ฐœ์—ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”."); + } + + public static void printInputArriveStation() { + System.out.println("## ๋„์ฐฉ์—ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”."); + } + + public static void printMinPathStationToArrive(String kind, Stack stack, int firstMinCost, int secondMinCost) { + System.out.println("[INFO] ---"); + if (kind.equals(Constants.DISTANCE_COST)) { + System.out.println("[INFO] ์ด ๊ฑฐ๋ฆฌ : " + firstMinCost); + System.out.println("[INFO] ์ด ์†Œ์š”์‹œ๊ฐ„ : " + secondMinCost); + } + if (kind.equals(Constants.TIME_COST)) { + System.out.println("[INFO] ์ด ์†Œ์š”์‹œ๊ฐ„ : " + firstMinCost); + System.out.println("[INFO] ์ด ๊ฑฐ๋ฆฌ : " + secondMinCost); + } + System.out.println("[INFO] ---"); + while (!stack.isEmpty()) { + System.out.println("[INFO] " + stack.pop()); + } + System.out.println(); + } +} diff --git a/src/main/java/subway/SubwayManagement.java b/src/main/java/subway/SubwayManagement.java new file mode 100644 index 000000000..21ed09e17 --- /dev/null +++ b/src/main/java/subway/SubwayManagement.java @@ -0,0 +1,82 @@ +package subway; + +import subway.domain.StationRepository; + +public class SubwayManagement { + + private User user; + + public SubwayManagement(User user) { + this.user = user; + } + + public void start() { + + InitSetting.initSetting(); + + while (true) { + PrintScreen.printMain(); + String select = user.getInput(); + try { + checkMainSelect(select); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + if (select.equals(Constants.FUNCTION_ONE)) { + findPathFunction(); + } + if (select.equals(Constants.FUNCTION_Q)) { + break; + } + } + } + + private void checkMainSelect(String select) { + if (!select.equals(Constants.FUNCTION_Q) && !select.equals(Constants.FUNCTION_ONE)) { + throw new IllegalArgumentException("[ERROR] ์„ ํƒํ•  ์ˆ˜ ์—†๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.\n"); + } + } + + private void findPathFunction() { + PrintScreen.selectStandard(); + String select = user.getInput(); + try { + checkFindPathSelect(select); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + if (select.equals(Constants.FUNCTION_ONE) || select.equals(Constants.FUNCTION_TWO)) { + selectFindPathFunction(select); + } + } + + private void checkFindPathSelect(String select) { + if (!select.equals(Constants.FUNCTION_ONE) && !select.equals(Constants.FUNCTION_TWO) && !select.equals(Constants.FUNCTION_B)) { + throw new IllegalArgumentException("[ERROR] ์„ ํƒํ•  ์ˆ˜ ์—†๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.\n"); + } + } + + private void selectFindPathFunction(String select) { + PrintScreen.printInputStartStation(); + String startStation = user.getInput(); + PrintScreen.printInputArriveStation(); + String arriveStation = user.getInput(); + + try { + checkFindPathInput(startStation, arriveStation); + FindPath.start(select, startStation, arriveStation); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return; + } + } + + private void checkFindPathInput(String startStation, String arriveStation) { + if (!StationRepository.isContain(startStation) || !StationRepository.isContain(arriveStation)) { + throw new IllegalArgumentException("[ERROR] ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์—ญ์ž…๋‹ˆ๋‹ค.\n"); + } + if (startStation.equals(arriveStation)) { + throw new IllegalArgumentException("[ERROR] ์ถœ๋ฐœ์—ญ๊ณผ ๋„์ฐฉ์—ญ์€ ๊ฐ™์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.\n"); + } + } +} diff --git a/src/main/java/subway/User.java b/src/main/java/subway/User.java new file mode 100644 index 000000000..7de1c3a59 --- /dev/null +++ b/src/main/java/subway/User.java @@ -0,0 +1,16 @@ +package subway; + +import java.util.Scanner; + +public class User { + + private final Scanner scanner; + + public User(Scanner scanner) { + this.scanner = scanner; + } + + public String getInput() { + return scanner.nextLine(); + } +} diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/Line.java index f4d738d5a..3c7427f86 100644 --- a/src/main/java/subway/domain/Line.java +++ b/src/main/java/subway/domain/Line.java @@ -1,7 +1,11 @@ package subway.domain; +import java.util.ArrayList; +import java.util.List; + public class Line { private String name; + private List sections = new ArrayList<>(); public Line(String name) { this.name = name; @@ -12,4 +16,7 @@ public String getName() { } // ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ + public void addStationInSection(String name) { + sections.add(new Station(name)); + } } diff --git a/src/main/java/subway/domain/LineRepository.java b/src/main/java/subway/domain/LineRepository.java index 2c4a723c9..d41305f8b 100644 --- a/src/main/java/subway/domain/LineRepository.java +++ b/src/main/java/subway/domain/LineRepository.java @@ -23,4 +23,8 @@ public static boolean deleteLineByName(String name) { public static void deleteAll() { lines.clear(); } + + public static void addSection(int idx, String stationName) { + lines.get(idx).addStationInSection(stationName); + } } diff --git a/src/main/java/subway/domain/NodeData.java b/src/main/java/subway/domain/NodeData.java new file mode 100644 index 000000000..c3a22c9cb --- /dev/null +++ b/src/main/java/subway/domain/NodeData.java @@ -0,0 +1,31 @@ +package subway.domain; + +public class NodeData { + private Station beforeStation; + private Station nextStation; + private int timeCost; + private int distanceCost; + + public NodeData(Station beforeStation, Station nextStation, int timeCost, int distanceCost) { + this.beforeStation = beforeStation; + this.nextStation = nextStation; + this.timeCost = timeCost; + this.distanceCost = distanceCost; + } + + public String getBeforeStation() { + return beforeStation.getName(); + } + + public String getNextStation() { + return nextStation.getName(); + } + + public int getTimeCost() { + return timeCost; + } + + public int getDistanceCost() { + return distanceCost; + } +} diff --git a/src/main/java/subway/domain/Station.java b/src/main/java/subway/domain/Station.java index bdb142590..a87c0f193 100644 --- a/src/main/java/subway/domain/Station.java +++ b/src/main/java/subway/domain/Station.java @@ -1,7 +1,12 @@ package subway.domain; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + public class Station { private String name; + private List nodeData = new ArrayList<>(); public Station(String name) { this.name = name; @@ -12,4 +17,11 @@ public String getName() { } // ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ + public void addNodeData(String nextStation, int timeCost, int distanceCost){ + nodeData.add(new NodeData(new Station(name), new Station(nextStation), timeCost, distanceCost)); + } + + public List getNodeData(){ + return Collections.unmodifiableList(nodeData); + } } diff --git a/src/main/java/subway/domain/StationRepository.java b/src/main/java/subway/domain/StationRepository.java index 8ed9d103f..81f483c5c 100644 --- a/src/main/java/subway/domain/StationRepository.java +++ b/src/main/java/subway/domain/StationRepository.java @@ -1,5 +1,7 @@ package subway.domain; +import subway.Constants; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -23,4 +25,58 @@ public static boolean deleteStation(String name) { public static void deleteAll() { stations.clear(); } + + public static boolean isContain(String name) { + for (Station station : stations) { + if (station.getName().equals(name)) { + return true; + } + } + + return false; + } + + public static int getSize() { + return stations.size(); + } + + public static int getCost(String firstStation, String secondStation, String kind) { + for (Station station : stations) { + if (station.getName().equals(firstStation)) { + return findNextStation(station, secondStation, kind); + } + } + return Constants.ERROR_CODE; + } + + private static int findNextStation(Station station, String nextStation, String kind) { + for (NodeData nodeData : station.getNodeData()) { + if (nodeData.getNextStation().equals(nextStation)) { + return getTimeOrDistanceCost(nodeData, kind); + } + } + return Constants.ERROR_CODE; + } + + private static int getTimeOrDistanceCost(NodeData nodeData, String kind) { + if (kind.equals(Constants.DISTANCE_COST)) { + return nodeData.getDistanceCost(); + } + if (kind.equals(Constants.TIME_COST)) { + return nodeData.getTimeCost(); + } + + return Constants.ERROR_CODE; + } + + public static void setCost(String prevStationName, String nextStationName, int timeCost, int distanceCost) { + for (int i = 0; i < stations.size(); i++) { + if (stations.get(i).getName().equals(prevStationName)) { + stations().get(i).addNodeData(nextStationName, timeCost, distanceCost); + } + if (stations.get(i).getName().equals(nextStationName)) { + stations.get(i).addNodeData(prevStationName, timeCost, distanceCost); + } + } + } }