From 9e3bf7551428e0d3848ded97d0f992df57ccafda Mon Sep 17 00:00:00 2001 From: CHONGMYOUNG LEE Date: Sun, 19 Oct 2025 18:17:15 +0900 Subject: [PATCH 1/7] =?UTF-8?q?[DOCS]:=20=EA=B5=AC=ED=98=84=ED=95=A0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bd90ef0247..387bb6d089 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ -# java-calculator-precourse \ No newline at end of file +# java-calculator-precourse + +1. 쉼표 혹은 콜론을 구분자로 가지는 문자열을 구분자 기준으로 분리한 각 숫자의 합을 반환 +2. 커스텀 구분자 지정 +3. 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시키기 \ No newline at end of file From e8a501649e9adadb91da593d04a8e2be1b1cbfab Mon Sep 17 00:00:00 2001 From: CHONGMYOUNG LEE Date: Sun, 19 Oct 2025 19:07:48 +0900 Subject: [PATCH 2/7] =?UTF-8?q?[FEAT]:=20=EA=B5=AC=EB=B6=84=EC=9E=90(,=20:?= =?UTF-8?q?)=EB=A1=9C=20=EB=8D=A7=EC=85=88=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/Application.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 573580fb40..9c27af31a0 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -1,7 +1,21 @@ package calculator; +import java.util.Scanner; +import static java.lang.Integer.parseInt; public class Application { + public static int calculator(String[] arr){ + int answer = 0; + for(String x : arr){ + answer += parseInt(x); + } + return answer; + } public static void main(String[] args) { // TODO: 프로그램 구현 + Scanner sc = new Scanner(System.in); + System.out.println("덧셈할 문자열을 입력해 주세요."); + String str = sc.nextLine(); + String arr[] = str.split(",|:"); + System.out.println("결과 : " + calculator(arr)); } -} +} \ No newline at end of file From da052a01d1dc65630339c2e08beea65adf517b32 Mon Sep 17 00:00:00 2001 From: CHONGMYOUNG LEE Date: Sun, 19 Oct 2025 19:56:19 +0900 Subject: [PATCH 3/7] =?UTF-8?q?[DOCS]=20README.md=20=EC=88=98=EC=A0=95(?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 387bb6d089..b3e97b0840 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,8 @@ 1. 쉼표 혹은 콜론을 구분자로 가지는 문자열을 구분자 기준으로 분리한 각 숫자의 합을 반환 2. 커스텀 구분자 지정 -3. 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시키기 \ No newline at end of file +3. 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시키기 + - 음수를 입력했을 때 + - 숫자가 아닌값을 입력했을 때 +4. 빈 문자열이나 null을 입력 받았을 때 +5. 숫자 하나를 입력 받았을 때 그대로 반환한다 \ No newline at end of file From c9bfa7912b42655664f66b984da60584631b2c97 Mon Sep 17 00:00:00 2001 From: CHONGMYOUNG LEE Date: Mon, 20 Oct 2025 16:26:50 +0900 Subject: [PATCH 4/7] =?UTF-8?q?[FEAT]=20StirngCalculator(=EB=B9=88=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=EC=97=B4=20=EB=98=90=EB=8A=94=20null=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EC=8B=9C=200=20=EB=B0=98=ED=99=98=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84,=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=20=EA=B5=AC=EB=B6=84=EC=9E=90=20=EC=A7=80=EC=9B=90=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80,=20=EC=9D=8C=EC=88=98?= =?UTF-8?q?=20=EB=98=90=EB=8A=94=20=EC=88=AB=EC=9E=90=EA=B0=80=20=EC=95=84?= =?UTF-8?q?=EB=8B=90=20=EA=B2=BD=EC=9A=B0=20=EC=98=88=EC=99=B8=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/StringCalculator.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/calculator/StringCalculator.java diff --git a/src/main/java/calculator/StringCalculator.java b/src/main/java/calculator/StringCalculator.java new file mode 100644 index 0000000000..2f0adf3709 --- /dev/null +++ b/src/main/java/calculator/StringCalculator.java @@ -0,0 +1,4 @@ +package calculator; + +public class StringCalculator { +} From 77aa7344f9ec16e65034eb9d4d5251dcfc45ddee Mon Sep 17 00:00:00 2001 From: CHONGMYOUNG LEE Date: Mon, 20 Oct 2025 16:27:45 +0900 Subject: [PATCH 5/7] =?UTF-8?q?[FEAT]=20StirngCalculator(=EB=B9=88=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=EC=97=B4=20=EB=98=90=EB=8A=94=20null=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EC=8B=9C=200=20=EB=B0=98=ED=99=98=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84,=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=20=EA=B5=AC=EB=B6=84=EC=9E=90=20=EC=A7=80=EC=9B=90=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80,=20=EC=9D=8C=EC=88=98?= =?UTF-8?q?=20=EB=98=90=EB=8A=94=20=EC=88=AB=EC=9E=90=EA=B0=80=20=EC=95=84?= =?UTF-8?q?=EB=8B=90=20=EA=B2=BD=EC=9A=B0=20=EC=98=88=EC=99=B8=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/calculator/StringCalculator.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/main/java/calculator/StringCalculator.java b/src/main/java/calculator/StringCalculator.java index 2f0adf3709..72bc032ff4 100644 --- a/src/main/java/calculator/StringCalculator.java +++ b/src/main/java/calculator/StringCalculator.java @@ -1,4 +1,51 @@ package calculator; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class StringCalculator { + + private static final Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile("//(.)\n(.*)"); + + public int add(final String text) { + // 1. 입력값이 null 이거나 비어있으면 0을 반환합니다. + if(text == null || text.isBlank()){ + return 0; + } + + // Matcher를 사용하여 커스텀 구분자 패턴과 일치하는지 확인합니다. + Matcher matcher = CUSTOM_DELIMITER_PATTERN.matcher(text); + if (matcher.find()) { + String customDelimiter = matcher.group(1); // 커스텀 구분자 + String numbersPart = matcher.group(2); // 숫자 구분 + return splitAndSum(numbersPart, customDelimiter); + } + // 커스첨 구분자가 없으면 기본 구분자를 사용하여 계산 + return splitAndSum(text, "[,:]"); + } + + private int splitAndSum(final String text, final String delimiter) { + // 구분자를 기준으로 문자열을 분리 + String[] numbers = text.split(delimiter); + + // 분리된 각 문자열을 숫자로 변환하고 합계를 구함 + return Arrays.stream(numbers) + .mapToInt(this::parseAndValidate) + .sum(); + } + + private int parseAndValidate(final String numberStr) { + try { + int number = Integer.parseInt(numberStr.trim()); + // 음수인지 확인하여 예외를 발생시킵니다. + if(number < 0){ + throw new IllegalArgumentException("음수는 입력할 수 없습니다."); + } + return number; + } catch (NumberFormatException e) { + // 숫자로 변환할 수 없는 경우 예외를 발생시킵니다. + throw new IllegalArgumentException("숫자가 아닌 값이 포함되어 있습니다."); + } + } } From 0d95b320760e519cdba656b72fd40629ce1add92 Mon Sep 17 00:00:00 2001 From: CHONGMYOUNG LEE Date: Mon, 20 Oct 2025 16:47:48 +0900 Subject: [PATCH 6/7] =?UTF-8?q?[FEAT]:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=9E=85=EC=B6=9C=EB=A0=A5=EC=9D=84=20=EC=9C=84=ED=95=9C=20App?= =?UTF-8?q?lication=20main=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/Application.java | 30 +++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 9c27af31a0..09f9b3cb73 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -1,21 +1,25 @@ package calculator; +import camp.nextstep.edu.missionutils.Console; + import java.util.Scanner; import static java.lang.Integer.parseInt; public class Application { - public static int calculator(String[] arr){ - int answer = 0; - for(String x : arr){ - answer += parseInt(x); - } - return answer; - } public static void main(String[] args) { - // TODO: 프로그램 구현 - Scanner sc = new Scanner(System.in); - System.out.println("덧셈할 문자열을 입력해 주세요."); - String str = sc.nextLine(); - String arr[] = str.split(",|:"); - System.out.println("결과 : " + calculator(arr)); + try { + // 사용자에게 입력을 요청합니다. + System.out.println("덧셈할 문자열을 입력해 주세요."); + String input = Console.readLine(); + + // 계산기 인스턴스 생성하고 덧셈을 수행합니다. + StringCalculator calculator = new StringCalculator(); + int result = calculator.add(input); + + // 결과를 출력합니다. + System.out.println("결과 : " + result); + } catch (IllegalArgumentException e) { + // 요구사항에 따라 잘못된 값 입력 시 예외 메시지를 출력하고 애플리케이션을 종료합니다. + System.err.println("[오류] " + e.getMessage()); + } } } \ No newline at end of file From 87131fc2ace1e8fc4398544af8f670d04ac497bc Mon Sep 17 00:00:00 2001 From: CHONGMYOUNG LEE Date: Mon, 20 Oct 2025 23:40:40 +0900 Subject: [PATCH 7/7] =?UTF-8?q?[FEAT]=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/Application.java | 26 +++---- .../java/calculator/StringCalculator.java | 8 +-- src/test/java/calculator/ApplicationTest.java | 70 +++++++++++++++++-- 3 files changed, 82 insertions(+), 22 deletions(-) diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 09f9b3cb73..8981ffa7b4 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -6,20 +6,22 @@ public class Application { public static void main(String[] args) { + // 사용자에게 입력을 요청합니다. + System.out.println("덧셈할 문자열을 입력해 주세요."); + + String input; try { - // 사용자에게 입력을 요청합니다. - System.out.println("덧셈할 문자열을 입력해 주세요."); - String input = Console.readLine(); + input = Console.readLine(); + } catch (Exception e) { + // 빈 입력이나 예외 발생 시 빈 문자열로 처리 + input = ""; + } - // 계산기 인스턴스 생성하고 덧셈을 수행합니다. - StringCalculator calculator = new StringCalculator(); - int result = calculator.add(input); + // 계산기 인스턴스 생성하고 덧셈을 수행합니다. + StringCalculator calculator = new StringCalculator(); + int result = calculator.add(input); - // 결과를 출력합니다. - System.out.println("결과 : " + result); - } catch (IllegalArgumentException e) { - // 요구사항에 따라 잘못된 값 입력 시 예외 메시지를 출력하고 애플리케이션을 종료합니다. - System.err.println("[오류] " + e.getMessage()); - } + // 결과를 출력합니다. + System.out.println("결과 : " + result); } } \ No newline at end of file diff --git a/src/main/java/calculator/StringCalculator.java b/src/main/java/calculator/StringCalculator.java index 72bc032ff4..d5e02dfaa4 100644 --- a/src/main/java/calculator/StringCalculator.java +++ b/src/main/java/calculator/StringCalculator.java @@ -6,11 +6,11 @@ public class StringCalculator { - private static final Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile("//(.)\n(.*)"); + private static final Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile("//(.)\\\\n(.*)"); public int add(final String text) { // 1. 입력값이 null 이거나 비어있으면 0을 반환합니다. - if(text == null || text.isBlank()){ + if(text == null || text.trim().isEmpty()){ return 0; } @@ -19,9 +19,9 @@ public int add(final String text) { if (matcher.find()) { String customDelimiter = matcher.group(1); // 커스텀 구분자 String numbersPart = matcher.group(2); // 숫자 구분 - return splitAndSum(numbersPart, customDelimiter); + return splitAndSum(numbersPart, Pattern.quote(customDelimiter)); } - // 커스첨 구분자가 없으면 기본 구분자를 사용하여 계산 + // 커스텀 구분자가 없으면 기본 구분자를 사용하여 계산 return splitAndSum(text, "[,:]"); } diff --git a/src/test/java/calculator/ApplicationTest.java b/src/test/java/calculator/ApplicationTest.java index 93771fb011..b8bbbf2506 100644 --- a/src/test/java/calculator/ApplicationTest.java +++ b/src/test/java/calculator/ApplicationTest.java @@ -1,6 +1,7 @@ package calculator; import camp.nextstep.edu.missionutils.test.NsTest; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static camp.nextstep.edu.missionutils.test.Assertions.assertSimpleTest; @@ -8,19 +9,76 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; class ApplicationTest extends NsTest { + + @Test + @DisplayName("기본 구분자(쉼표)를 사용한 덧셈") + void 기본_구분자_쉼표() { + assertSimpleTest(() -> { + run("1,2,3"); + assertThat(output()).contains("결과 : 6"); + }); + } + + @Test + @DisplayName("기본 구분자(콜론)를 사용한 덧셈") + void 기본_구분자_콜론() { + assertSimpleTest(() -> { + run("1:2:3"); + assertThat(output()).contains("결과 : 6"); + }); + } + + @Test + @DisplayName("기본 구분자(쉼표와 콜론 혼용)를 사용한 덧셈") + void 기본_구분자_혼용() { + assertSimpleTest(() -> { + run("1,2:3"); + assertThat(output()).contains("결과 : 6"); + }); + } + @Test - void 커스텀_구분자_사용() { + @DisplayName("커스텀 구분자를 사용한 덧셈") + void 커스텀_구분자_덧셈() { assertSimpleTest(() -> { - run("//;\\n1"); - assertThat(output()).contains("결과 : 1"); + run("//;\n1;2;3"); + assertThat(output()).contains("결과 : 6"); }); } @Test - void 예외_테스트() { + @DisplayName("단일 숫자 입력 시 해당 숫자 반환") + void 단일_숫자() { + assertSimpleTest(() -> { + run("5"); + assertThat(output()).contains("결과 : 5"); + }); + } + + @Test + @DisplayName("빈 문자열 또는 null 입력 시 0 반환") + void 빈_문자열_또는_null() { + assertSimpleTest(() -> { + run(""); + assertThat(output()).contains("결과 : 0"); + }); + } + + @Test + @DisplayName("음수 입력 시 IllegalArgumentException 발생") + void 음수_예외() { + assertSimpleTest(() -> + assertThatThrownBy(() -> runException("-1,2,3")) + .isInstanceOf(IllegalArgumentException.class) + ); + } + + @Test + @DisplayName("숫자가 아닌 문자 입력 시 IllegalArgumentException 발생") + void 숫자가_아닌_문자_예외() { assertSimpleTest(() -> - assertThatThrownBy(() -> runException("-1,2,3")) - .isInstanceOf(IllegalArgumentException.class) + assertThatThrownBy(() -> runException("1,a,2")) + .isInstanceOf(IllegalArgumentException.class) ); }