Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
# java-calculator-precourse
# 문자열 덧셈 계산기

## 구현할 기능 목록

- [x] 빈 문자열 또는 null 값을 입력할 경우 0을 반환한다.
- [x] 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우, 구분자를 기준으로 분리한 각 숫자의 합을 반환한다.
- [x] 커스텀 구분자를 지정할 수 있다.
- 커스텀 구분자는 문자열 앞부분의 "//"와 "\n" 사이에 위치하는 문자를 사용한다.
- 예: `//;\n1;2;3` => 구분자: `;`, 결과: `6`
- [x] 음수를 입력할 경우 `IllegalArgumentException`을 발생시킨다.
- [x] 숫자가 아닌 값을 입력할 경우 `IllegalArgumentException`을 발생시킨다.
- [x] 사용자가 입력을 하고, 결과를 출력하는 UI를 구현한다.
14 changes: 13 additions & 1 deletion src/main/java/calculator/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
package calculator;

import camp.nextstep.edu.missionutils.Console;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
StringCalculator calculator = new StringCalculator();

System.out.println("덧셈할 문자열을 입력해 주세요.");
String input = Console.readLine();

try {
int result = calculator.add(input);
System.out.println("결과 : " + result);
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
}
53 changes: 53 additions & 0 deletions src/main/java/calculator/StringCalculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package calculator;

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;

public class StringCalculator {

private static final Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile("//(.)\n(.*)");
private static final String DEFAULT_DELIMITERS = "[,:]";

public int add(String text) {
if (text == null || text.isBlank()) {
return 0;
}

String[] numbers = split(text);
IntStream stream = toIntStream(numbers);

return sum(stream);
}

private String[] split(String text) {
Matcher matcher = CUSTOM_DELIMITER_PATTERN.matcher(text);
if (matcher.find()) {
String customDelimiter = matcher.group(1);
String numbersText = matcher.group(2);
return numbersText.split(Pattern.quote(customDelimiter));
}
return text.split(DEFAULT_DELIMITERS);
}

private IntStream toIntStream(String[] numbers) {
try {
return Arrays.stream(numbers)
.mapToInt(Integer::parseInt);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("숫자가 아닌 값이 포함되어 있습니다.");
}
}

private int sum(IntStream stream) {
int[] numbers = stream.toArray();

long negativeCount = Arrays.stream(numbers).filter(n -> n < 0).count();
if (negativeCount > 0) {
throw new IllegalArgumentException("음수는 입력할 수 없습니다.");
}

return Arrays.stream(numbers).sum();
}
}