diff --git a/README.md b/README.md index bd90ef0247..f4f02c82d6 100644 --- a/README.md +++ b/README.md @@ -1 +1,39 @@ -# java-calculator-precourse \ No newline at end of file +# java-calculator-precourse + +## 입력한 문자열에서 숫자를 추출하여 더하기를 계산하는 프로그램 + +### 기능설명 + +1. 기본 구분자(쉼표, 콜론)로 구성된 문자열의 결과 계산 + +예: + +```` +입력: 1,2,3 +```` +``` +출력: 6 +``` +--- +2. 커스텀 구분자로 구성된 문자열 계산 +예: + +``` +입력: //-\n1-2-3 +``` +``` +출력: 6 +``` +--- +3. 잘못된 입력값 처리 + +### 기능목록 + +1. Application 의 main()에서 입력,출력 결과 처리 + Note: 빈 입력이면 0 반환 + +2. Regex을 이용해 구분자로 분리 후 결과 계산 + +3. 유효하지 않은 문자열 확인후 IllegalArgumentException 후 프로그램 종료 + + diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 573580fb40..59766c6775 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -1,7 +1,23 @@ package calculator; +import camp.nextstep.edu.missionutils.Console; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + System.out.println("덧셈할 문자열을 입력해 주세요."); + String first = Console.readLine(); + + String input = first; + if (first != null && first.contains("\\n")) { + input = first.replace("\\n", "\n"); + } + + else if (first != null && first.startsWith("//")) { + String numbers = Console.readLine(); + input = first + "\n" + (numbers == null ? "" : numbers); + } + + int result = Calculator.add(input); + System.out.println("결과 : " + result); } } diff --git a/src/main/java/calculator/Calculator.java b/src/main/java/calculator/Calculator.java new file mode 100644 index 0000000000..8a3f37a940 --- /dev/null +++ b/src/main/java/calculator/Calculator.java @@ -0,0 +1,62 @@ +package calculator; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Calculator { + private static final Pattern CUSTOM_PATTERN = + Pattern.compile("^//(?.+)\\n(?.*)$"); + private static final String DEFAULT_PATTERN = "[,:]"; + public static int add(String input) { + if (input == null || input.isEmpty()) { + return 0; + } + + InputType inputStr = checkInputType(input); // custom 인지 default 인지 구분해서 sep,num 인 InputType 반환 + String[] values = filter(inputStr); // 검사전 값들 + + int sum = 0; + for (String value : values) { + validate(value); // 유효성 검사 + int num = Integer.parseInt(value); + if (num < 0) { + throw new IllegalArgumentException("음수는 허용되지 않습니다: " + value); + } + sum += num; + } + return sum; + } + private static InputType checkInputType(String input) { + Matcher m = CUSTOM_PATTERN.matcher(input); + if (m.matches()) { + String rawSep = m.group("sep"); + String ignore = Pattern.quote(rawSep); + return new InputType(ignore, m.group("numbers")); + } + return new InputType(DEFAULT_PATTERN, input); + } + private static String[] filter(InputType str) { + String regex = DEFAULT_PATTERN; + if (!str.sep.equals(DEFAULT_PATTERN)) { + regex = DEFAULT_PATTERN + "|" + str.sep; + } + return str.numbers.split(regex, -1); + } + private static void validate(String value) { + if (value == null || value.isEmpty()) { + throw new IllegalArgumentException("비어 있는 숫자 토큰이 있습니다."); + } + if (!value.chars().allMatch(Character::isDigit)) { + throw new IllegalArgumentException("숫자가 아닌 값 발견: " + value); + } + } + private static final class InputType { + final String sep; + final String numbers; + InputType(String sep, String numbers) { + this.sep = sep; + this.numbers = numbers; + } + } + +}