diff --git a/README.md b/README.md index bd90ef0..79fddc1 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ -# java-calculator-precourse \ No newline at end of file +# java-calculator-precourse +1. 정규표현식을 사용해서 문자열 구분자를 이용한 덧셈처리 diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 573580f..87a89b1 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -1,7 +1,55 @@ package calculator; +import camp.nextstep.edu.missionutils.Console; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + String string = Console.readLine(); + //정규표현식을 통해서 입력받은 문자열이 //(문자)\n의 형태인지 아닌지를 확인한다. + //실제개행문자(\n)가 아니기때문에 문자열 백슬래시를 이스케이프를 진행 + String patternString = "^(?://(.{1})\\\\n(.*)|(?!//).*)$"; + Pattern pattern = Pattern.compile(patternString); + Matcher matcher = pattern.matcher(string); + boolean isContain = matcher.matches(); + if (isContain){ + //구분자와 구분자를 제외한 수식 변수를 만든다 + String delimiter; + String expression; + //커스텀구분자를 제작한다면 커스텀구분자가 있는 그룹과 수식이 있는 그룹으로 나눈다. + String customDelimiter = matcher.group(1); + String rest = matcher.group(2); + + if (customDelimiter != null) { + //커스텀 구분자가 존재한다면 해당 값을 구분자 변수에 넣어 준다. + //수식이 있는 부분을 수식 변수에 넣어 준다. + delimiter = customDelimiter; + expression = rest; + } else { + //기본 구분자는 :와 ,인데 하나로 통일해주기 위해서 :로 통일해준다. + delimiter = ":"; + expression = matcher.group(0); + expression = expression.replace(",", delimiter); + } + //구분자로 수식을 나눈다. + delimiter = Pattern.quote(delimiter); + String[] splitExpression = expression.split(delimiter); + int sum = 0; + //소수를 표현하기 위한 .이 있으면 소수가 아니라 구분자로 인식될 것이기에 소수는 없다고 생각해도 된다. + for (int i =0; i < splitExpression.length; i++){ + if (!splitExpression[i].matches("^[1-9][0-9]*$")) { + //양수에는 0이 없다. 0이 나와도 에러 처리를 진행한다. + throw new IllegalArgumentException("Charactor that isn't delimiter is in this expression"); + } else{ + sum += Integer.parseInt(splitExpression[i]); + } + } + System.out.println("결과 : "+sum); + } else{ + throw new IllegalArgumentException("Not in rule. Can't caculate this expression"); + } } } diff --git a/src/test/java/calculator/ApplicationTest.java b/src/test/java/calculator/ApplicationTest.java index 93771fb..57e40d7 100644 --- a/src/test/java/calculator/ApplicationTest.java +++ b/src/test/java/calculator/ApplicationTest.java @@ -10,18 +10,65 @@ class ApplicationTest extends NsTest { @Test void 커스텀_구분자_사용() { + //기본 테스트 assertSimpleTest(() -> { run("//;\\n1"); assertThat(output()).contains("결과 : 1"); }); + //기본 테스트 + assertSimpleTest(() -> { + run("1,2:3"); + assertThat(output()).contains("결과 : 6"); + }); + //두 자릿 수 이상의 숫자 + assertSimpleTest(() -> { + run("//;\\n1;21;361"); + assertThat(output()).contains("결과 : 383"); + }); + //두 자릿 수 이상의 숫자 + assertSimpleTest(() -> { + run("//;\\n4;30;200"); + assertThat(output()).contains("결과 : 234"); + }); + //구분자 ^로 변경 + assertSimpleTest(() -> { + run("//^\\n3^7^9"); + assertThat(output()).contains("결과 : 19"); + }); + //구분자 @로 변경 + assertSimpleTest(() -> { + run("//@\\n19@8"); + assertThat(output()).contains("결과 : 27"); + }); } @Test void 예외_테스트() { + //기본 예외 assertSimpleTest(() -> assertThatThrownBy(() -> runException("-1,2,3")) .isInstanceOf(IllegalArgumentException.class) ); + //소수 or .구분자가 아닌 문자 사용 + assertSimpleTest(() -> + assertThatThrownBy(() -> runException("1.3:3")) + .isInstanceOf(IllegalArgumentException.class) + ); + //커스텀 구분자 명시하는 패턴 사이 문자가 두개 이상 + assertSimpleTest(() -> + assertThatThrownBy(() -> runException("//*&\\n1*&2*&3")) + .isInstanceOf(IllegalArgumentException.class) + ); + //숫자 사이에 구분자가 아닌 문자 + assertSimpleTest(() -> + assertThatThrownBy(() -> runException("//)\\n1*7)3")) + .isInstanceOf(IllegalArgumentException.class) + ); + //0(양의 정수만 가능, .는 문자가 될 수 있어 소수 불가능) + assertSimpleTest(() -> + assertThatThrownBy(() -> runException("//#\\n0#30")) + .isInstanceOf(IllegalArgumentException.class) + ); } @Override