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
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
## 1. 문자열 덧셈 계산기
### 요구사항
- : 또는 ,를 구분자로 한다. `Separator#separate`
- 커스텀 구분자를 지정할 수 있다.
1. //와 \n 사이에 입력한 값이 커스텀 구분자가 된다. -> //로 시작하면 \n만날 때까지 값을 구분자에 저장한다. `Separator#getCustomSeparator`
2. //&\n1&2&3 -> 1+2+3 = 6 -> (커스텀)구분자 이용해서 덧셈 진행 -> `Calculator#plus`
- 숫자이외의 값 혹은 음수를 입력할 경우 RuntimeException을 던진다. -> `Calculator#isCorrectNumeric`

<추가 제한 사항>
- 커스텀 지정한 경우 입력 시, 지정 커스텀으로만 구성한다.
- 커스텀은 한글자이어야 한다.

---

## [NEXTSTEP 플레이그라운드의 미션 진행 과정](https://github.com/next-step/nextstep-docs/blob/master/playground/README.md)

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

import java.util.ArrayList;
import java.util.List;

public class Calculator {
private static final String MINUS_REGEX = "-";

public int plus(String[] input) {
int sum = 0;
checkCorrectNumeric(input);

List<Integer> nums = changeToIntNums(input);
for(int num : nums) {
sum += num;
}
return sum;
}
// 1. 숫자 이외의 값 있는지 검증 2. 음수인지 검증
private List<Integer> changeToIntNums(String[] input) {
List<Integer> nums = new ArrayList<>();
for (String i : input) {
nums.add(Integer.parseInt(i));
}
return nums;
}

private boolean isNullOrEmpty(String str) {
return str == null || "".equals(str);
}

/**
* 1. 정규식
* 2. Double.parseDouble()을 통해 catch문 시 return false
* TODO two depth...
*/
private void checkCorrectNumeric(String[] str) {
for (int i = 0; i < str.length; i++) {
if(isNullOrEmpty(str[i])) {
str[i] = "0";
continue;
}
if(str[i].matches("[^0-9]")) {
throw new RuntimeException("숫자 외의 값은 불가능합니다.");
}
if (str[i].startsWith(MINUS_REGEX)) {
throw new RuntimeException("0 이상의 정수만 가능합니다.");
}
}
}
}
41 changes: 41 additions & 0 deletions src/main/java/calculator/Separator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package calculator;

/**
* 새로 알게된 점
* 1. 개행문자(\n)의 \는 2개 적어주어야 한다. ex) "\\n"
* 2. 몇몇 문자(+,^,*)는 코드 상 의미를 가지기 때문에 "//"를 붙여줘야 한다.
*/
public class Separator {
private static final String CUSTOM_REGEX_PREFIX = "//";
private static final String CUSTOM_REGEX_SUFFIX = "\n";
public String[] separate(String input) {
String regex = ",|:";
if (input.startsWith(CUSTOM_REGEX_PREFIX)) {
regex = getCustomSeparator(input);
input = deleteRegex(input, regex);
}
if (hasRegexMeaning(regex)) {
regex = "\\"+ regex;
}
return input.split(regex);
}
// 의미있는 구분자를 사용하는가? (+, ^, *)
private boolean hasRegexMeaning(String regex) {
return "+^*".contains(regex);
}

// "//*\n1*2*3"
private String deleteRegex(String input, String regex) {
int total = CUSTOM_REGEX_PREFIX.length() + CUSTOM_REGEX_SUFFIX.length() + regex.length();
return input.substring(total);
}
private String getCustomSeparator(String inputWithCustomRegex) {
for (int i=2; i< inputWithCustomRegex.length()-1; i++) {
String tmp = inputWithCustomRegex.substring(i, i + 1); // substring(a,b) : a부터 b 위치 포함 값까지
if (CUSTOM_REGEX_SUFFIX.equals(tmp)) {
return inputWithCustomRegex.substring(2, i);
}
}
throw new RuntimeException("알맞은 구분자가 아닙니다.");
}
}
36 changes: 36 additions & 0 deletions src/test/java/calculator/CalculatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package calculator;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class CalculatorTest {

@Test
@DisplayName("실패 - 숫자 이외의 값 혹은 음수를 던진다.")
void plusFailedTest() {
String[] inputWithMinus = new String[]{"1", "-1", "0"};
String[] inputWithAlphabet = new String[]{"1", "-", "a"};
Calculator cal = new Calculator();
Assertions.assertThrows(RuntimeException.class, () -> cal.plus(inputWithMinus));
Assertions.assertThrows(RuntimeException.class, () -> cal.plus(inputWithAlphabet));
}

@Test
@DisplayName("빈 문자를 던진다.")
void nullTest() {
String[] inputWithNull = new String[]{null};
Calculator cal = new Calculator();
assertThat(cal.plus(inputWithNull)).isEqualTo(0);
}

@Test
@DisplayName("주어진 배열 숫자로 덧셈한다.")
void plusTest() {
String[] input = new String[]{"1","2","3"};
Calculator cal = new Calculator();
assertThat(cal.plus(input)).isEqualTo(1+2+3);
}
}
42 changes: 42 additions & 0 deletions src/test/java/calculator/SeparatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package calculator;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class SeparatorTest {

@Test
@DisplayName("기본 구분자(,|:)로 구분한다.")
void basicTwoSeparatorsTest() {
Separator separator = new Separator();
String input = "1,2:3";
assertThat(separator.separate(input)).isEqualTo(new String[]{"1","2","3"});
}
@Test
@DisplayName("기본 구분자(,)로 구분한다.")
void basicOneSeparatorTest() {
Separator separator = new Separator();
String input = "1,2";
assertThat(separator.separate(input)).isEqualTo(new String[]{"1","2"});
}

@Test
@DisplayName("커스텀 구분자로 구분한다.")
void customSeparatorTest() {
Separator separator = new Separator();
String inputWithStarSplit = "//*\n1*2*3";
String inputWithCollonSplit = "//;\n1;2;3";
assertThat(separator.separate(inputWithStarSplit)).isEqualTo(new String[]{"1","2","3"});
assertThat(separator.separate(inputWithCollonSplit)).isEqualTo(new String[]{"1","2","3"});
}

@Test
@DisplayName("숫자 한개만 입력한다.")
void inputOnlyOneNumberTest() {
Separator separator = new Separator();
String input = "1";
assertThat(separator.separate(input)).isEqualTo(new String[]{"1"});
}
}