-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LBP] 윤준석 3, 4단계 과제 제출합니다. #74
Changes from 4 commits
30862c7
5ea3434
cbba6ea
0914fac
11e3ccf
a489324
27d5b9e
d13d70a
bbc05d2
cf683c9
d20e9a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,62 @@ | ||
import java.util.regex.Pattern; | ||
|
||
|
||
/** | ||
* 문자열을 숫자로 변환하여 합산하는 계산기임. <br> | ||
* 쉼표 또는 콜론을 기본 구분자로 사용함.<br> | ||
* //<구분자>\n 해당 위치에 원하는 구분자를 넣으면,<br> | ||
* 단일 문자로 커스텀 구분자 지정이 가능함.<br> | ||
* //@\n1:2@3,4 같은 형식도 처리 가능<br> | ||
* 음수나 숫자가 아닌 값이 포함되면 예외를 발생시킴. | ||
*/ | ||
public class StringCalculator { | ||
|
||
// 기본 구분자 | ||
private static final String DEFAULT_DELIMITER = "[,|:]"; | ||
private static final String CUSTOM_DELIMITER_PREFIX = "//"; | ||
private static final String NEW_LINE = "\n"; | ||
private static final int CUSTOM_DELIMITER_PREFIX_LENGTH = 2; | ||
|
||
public static int add(String input) { | ||
if (input.isEmpty()) { | ||
return 0; | ||
} | ||
|
||
String delimiter = "[,|:]"; // 기본 구분자 정의 | ||
String delimiter = DEFAULT_DELIMITER; // 기본 구분자 정의 | ||
|
||
if (input.startsWith("//")) { // 커스텀 구분자 처리 (여러 글자 지원) | ||
int delimiterEnd = input.indexOf("\n"); | ||
String customDelimiter = input.substring(2, delimiterEnd); | ||
delimiter = "[,|:]|" + Pattern.quote(customDelimiter); | ||
if (input.startsWith(CUSTOM_DELIMITER_PREFIX)) { // 커스텀 구분자 처리 (여러 글자 지원) | ||
int delimiterEnd = input.indexOf(NEW_LINE); | ||
String customDelimiter = input.substring(CUSTOM_DELIMITER_PREFIX_LENGTH, delimiterEnd); | ||
delimiter = DEFAULT_DELIMITER + "|" + Pattern.quote(customDelimiter); | ||
input = input.substring(delimiterEnd + 1); | ||
} | ||
|
||
String[] numbers = input.split(Pattern.compile(delimiter).pattern()); | ||
Pattern pattern = Pattern.compile(delimiter); | ||
String[] numbers = pattern.split(input); | ||
return sum(numbers); | ||
} | ||
|
||
public static int sum(String[] numbers) { //문자열을 숫자로 변환하여 합을 계산 | ||
private static int sum(String[] numbers) { // 문자열을 숫자로 변환하여 합을 계산 | ||
int sum = 0; | ||
StringBuilder negativeNumber = new StringBuilder(); // 음수가 포함될 경우 예외메시지 만드는데 사용 | ||
StringBuilder negativeNumbers = new StringBuilder(); // 음수값을 저장 | ||
|
||
for (String num : numbers) { | ||
int value; | ||
|
||
try { | ||
value = Integer.parseInt(num); // parseInt 사용하여 문자열을 숫자로 변환 | ||
} catch (NumberFormatException e) { | ||
// 숫자가 아닌 값이 포함되면 런타임 에러 발생 | ||
throw new RuntimeException("Invalid input: 숫자가 아닌 값이 포함되었습니다."); | ||
} | ||
// 음수값이 발견되면 negativeNumber에 추가 | ||
if (value < 0) { | ||
negativeNumber.append(value).append(" "); | ||
} | ||
|
||
int value = parseAndValidateNumber(num, negativeNumbers); // 숫자 변환 및 검증 | ||
sum += value; | ||
} | ||
// 음수값이 있는 경우 예외처리 | ||
if (!negativeNumber.isEmpty()) { | ||
throw new RuntimeException("입력한 값 중 음수 값이 존재합니다.: " + negativeNumber.toString().trim()); | ||
|
||
// 음수값이 존재하면 예외 발생 | ||
if (!negativeNumbers.isEmpty()) { | ||
throw new RuntimeException("입력한 값 중 음수 값이 존재합니다: " + negativeNumbers.toString().trim()); | ||
} | ||
|
||
return sum; | ||
} | ||
|
||
private static int parseAndValidateNumber(String num, StringBuilder negativeNumbers) { | ||
int value; | ||
|
||
try { | ||
value = Integer.parseInt(num); | ||
} catch (NumberFormatException e) { | ||
throw new RuntimeException("Invalid input: 숫자가 아닌 값이 포함되었습니다."); | ||
} | ||
|
||
if (value < 0) { | ||
negativeNumbers.append(value).append(" "); | ||
} | ||
|
||
return value; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.CsvSource; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
|
@@ -13,11 +15,15 @@ void testEmptyStringReturnsZero() { | |
.isEqualTo(0); | ||
} | ||
|
||
@Test | ||
@DisplayName("단일 숫자 출력 기능") | ||
void testSingleNumber() { | ||
assertThat(StringCalculator.add("1")).isEqualTo(1); | ||
assertThat(StringCalculator.add("5")).isEqualTo(5); | ||
@ParameterizedTest | ||
@DisplayName("단일 숫자 입력 테스트") | ||
@CsvSource({ | ||
"1, 1", | ||
"5, 5", | ||
"10, 10" | ||
}) | ||
void testSingleNumber(String input, int expected) { | ||
assertThat(StringCalculator.add(input)).isEqualTo(expected); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 굿! 👍 |
||
|
||
@Test | ||
|
@@ -40,28 +46,36 @@ void testCustomDelimiter() { | |
assertThat(StringCalculator.add("//|\n2,3|50")).isEqualTo(55); | ||
} | ||
|
||
@Test | ||
@ParameterizedTest | ||
@DisplayName("특수문자가 포함된 커스텀 구분자를 사용한 숫자 합산 기능") | ||
void testCustomDelimiterWithSpecialCharacters() { | ||
assertThat(StringCalculator.add("//.\n2.3.5")).isEqualTo(10); | ||
assertThat(StringCalculator.add("//$\n1$2$3")).isEqualTo(6); | ||
@CsvSource({ | ||
"'//.\n2.3.5', 10", | ||
"'//$\n1$2$3', 6" | ||
}) | ||
void testCustomDelimiterWithSpecialCharacters(String input, int expected) { | ||
assertThat(StringCalculator.add(input)).isEqualTo(expected); | ||
} | ||
|
||
@Test | ||
@DisplayName("입력값 중 음수가 존재하는 경우를 식별하는 기능") | ||
@DisplayName("입력값 중 음수가 존재하는 경우 예외 발생") | ||
void testNegativeNumbersThrowException() { | ||
assertThatThrownBy(() -> StringCalculator.add("1,-2,3")) | ||
String input = "1,-2,3"; | ||
String expectedMessage = "입력한 값 중 음수 값이 존재합니다: -2"; | ||
|
||
assertThatThrownBy(() -> StringCalculator.add(input)) | ||
.isInstanceOf(RuntimeException.class) | ||
.hasMessageContaining("입력한 값 중 음수 값이 존재합니다."); | ||
.hasMessage(expectedMessage); // 예외 메시지가 정확히 일치하는지 검증 | ||
} | ||
|
||
@Test | ||
@DisplayName("입력값이 숫자가 아닌 값이 존재하는 경우를 식별하는 기능") | ||
@DisplayName("입력값이 숫자가 아닌 값이 존재하는 경우 예외 발생") | ||
void testNonNumericValuesThrowException() { | ||
assertThatThrownBy(() -> StringCalculator.add("1,a,3")) | ||
.isInstanceOf(RuntimeException.class); | ||
.isInstanceOf(RuntimeException.class) | ||
.hasMessage("Invalid input: 숫자가 아닌 값이 포함되었습니다."); | ||
|
||
assertThatThrownBy(() -> StringCalculator.add("//;\n1;B;3")) | ||
.isInstanceOf(RuntimeException.class); | ||
.isInstanceOf(RuntimeException.class) | ||
.hasMessage("Invalid input: 숫자가 아닌 값이 포함되었습니다."); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 두 친구도 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 반영 완료! |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
생각해보니 어차피 예외를 던질 코드라면 입력된 모든 음수를 파악해서 알리는 것보다
아래
parseAndValidateNumber()
의 조건문에서 바로 예외를 던지는 편이 더 낫지 않을까요?준석의 생각은 어떤가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영 완료했습니다!