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
35 changes: 34 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,34 @@
# java-calculator-precourse
# java-calculator-precourse

## 1) 목표
인풋 문자열로부터 기준에 따라 양의 정수를 추출하여 합을 반환하는 프로그램 작성

## 2) 입출력 정의
- **Input**: `camp.nextstep.edu.missionutils.Console.readLine()` 을 이용.
- **Output**: `결과 : <sum>` 형태로 출력.
- **예외로 인한 종료**: `IllegalArgumentException` 을 Throw (`System.exit()` 호출 **금지** ).

## 3) 추출 규칙
1. **기본 구분자(delimiter)**: comma (`,`) and colon (`:`).
- 예시: `"" -> 0`, `"1,2" -> 3`, `"1,2,3" -> 6`, `"1,2:3" -> 6`
2. **커스텀 구분자**: `"//<커스텀구분자>\n<숫자>"`
- 예시: `"//;\n1;2;3" -> 6` (커스텀 구분자는 `;`)
3. **유효 토큰**: 모든 숫자는 **양수** ( > 0 ).
4. **공백**: 일단 trimming 은 고려 X

## 4) 예외 규칙 (`IllegalArgumentException`)
- 음수 등장 시 ( ex: `-1,2`).
- 기본 구분자, 커스텀 구분자를 제외한 입력값 등장 시
- 커스텀 구분 등장 시, 문법을 지키지 않을 시


## 5) Output Format
- 성공 시: `결과 : <sum>`
- 실패 시: throw `IllegalArgumentException`

## 6) 그 외 Constraints
- **JDK 21**.
- **Entry point**: `Application.main(String[] args)`.
- 제공된 **Console API** 사용: `Console.readLine()`.
- **수정 X** `build.gradle`. 외부 라이브러리 X, 제공된 라이브러리만 사용
- **사용 X** `System.exit()`.
13 changes: 12 additions & 1 deletion src/main/java/calculator/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
package calculator;

import camp.nextstep.edu.missionutils.Console;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
System.out.println("덧셈할 문자열을 입력해 주세요.");
String input = Console.readLine();

StringCalculator calculator = new StringCalculator();
int result = calculator.add(input);

System.out.println("결과 : " + result);
}
}

}

58 changes: 58 additions & 0 deletions src/main/java/calculator/StringCalculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package calculator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringCalculator {

private static final Pattern DEFAULT_DELIMS = Pattern.compile("[,:]");
private static final Pattern CUSTOM_HEADER = Pattern.compile("^//(.)\\n(.*)$", Pattern.DOTALL);

public int add(String input) {
// Null 문자열은 0 반환
if (input == null || input.trim().isEmpty()) {
return 0;
}

Matcher m = CUSTOM_HEADER.matcher(input);
if (m.matches()) {
String delim = m.group(1);
String body = m.group(2);
if (body == null || body.trim().isEmpty()) {
return 0;
}
String regex = Pattern.quote(delim);
String[] tokens = body.split(regex, -1);
return sumTokens(tokens);
}

// '//'로 시작하나 커스텀 구분자 문법이 잘못 됐을 때
if (input.startsWith("//")) {
throw new IllegalArgumentException("커스텀 구분자 형식이 잘못됐습니다.");
}

String[] tokens = DEFAULT_DELIMS.split(input, -1);
return sumTokens(tokens);
}

private int sumTokens(String[] tokens) {
if (tokens.length == 0) {
throw new IllegalArgumentException("tokens가 비어있음");
}
int sum = 0;
for (String token : tokens) {
if (token.isEmpty()) {
throw new IllegalArgumentException("token이 비어있음");
}
if (!token.chars().allMatch(Character::isDigit)) {
throw new IllegalArgumentException("숫자가 아닌 token: " + token);
}
int value = Integer.parseInt(token);
if (value <= 0) {
throw new IllegalArgumentException("양수가 아닌 number: " + token);
}
sum += value;
}
return sum;
}
}