diff --git a/README.md b/README.md index 8fe7112..0eec09a 100644 --- a/README.md +++ b/README.md @@ -24,3 +24,32 @@ git checkout main // 기본 브랜치가 main인 경우 git checkout -b 브랜치이름 ex) git checkout -b apply-feedback ``` +요구사항 +사용자가 입력한 문자열 값에 따라 사칙연산을 수행할 수 있는 계산기를 구현해야 한다. +문자열 계산기는 사칙연산의 계산 우선순위가 아닌 입력 값에 따라 계산 순서가 결정된다. +즉, 수학에서는 곱셈, 나눗셈이 덧셈, 뺄셈 보다 먼저 계산해야 하지만 이를 무시한다. +예를 들어 "2 + 3 * 4 / 2"와 같은 문자열을 입력할 경우 2 + 3 * 4 / 2 실행 결과인 10을 출력해야 한다. + +힌트 +문자열을 입력 받은 후(scanner의 nextLine() 메소드 활용) 빈 공백 문자열을 기준으로 문자들을 분리해야 한다. +String value = scanner.nextLine(); +String[] values = value.split(" "); +문자열을 숫자로 변경하는 방법 +int number = Integer.parseInt("문자열"); + +- 단순 계산기(SimpleCalculator) + - [x] 주어진 사칙연산기호를 통해 두 개의 숫자를 계산한다. + - 사칙연산 기호(symbol) + - [x] `+`->두 개의 숫자를 덧셈 + - [x] `-`->두 개의 숫자를 뺄셈 + - [x] `*`->두 개의 숫자를 곱셈 + - [x] `/`->두 개의 숫자를 나눗셈 + - [x] 0으로 나누면 throw new ArithmeticException(); + +- 방정식 (Equation) + - [x] 문자열을 문자들로 분리 + - [x] 분리된 문자들 중 숫자만 반환 + - [x] 분리된 문자들 중 연산기호만 반환 + +- 문자열 계산기() + - [ ] 문자열 변환기와 단순 계산기를 통해 계산된 결과를 보여준다. diff --git a/src/main/java/study/Equation.java b/src/main/java/study/Equation.java new file mode 100644 index 0000000..e9193c3 --- /dev/null +++ b/src/main/java/study/Equation.java @@ -0,0 +1,82 @@ +package study; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Equation { + + private final String equation; + + private static final String INVALID_CALCULATION_FORMAT = "잘못된 계산식입니다."; + private static final String DELIMITER = " "; + + public Equation(String equation) { + this.equation = equation; + checkEquation(); + } + + public void checkEquation() { + String[] split = equation.split(DELIMITER); + + for (int i = 0; i < split.length; ) { + checkDoubleNumber(split, i); + i += 2; + } + + for (int i = 1; i < split.length; ) { + checkDoubleSymbol(split, i); + i += 2; + } + + } + + public List getNumbers() { + List numList = new ArrayList<>(); + String[] inputArr = equation.split(DELIMITER); + Arrays.stream(inputArr).filter(this::isParesInt).forEach(s -> addNumList(numList, s)); + return numList; + } + + public List getSymbolsList() { + List symbolList = new ArrayList<>(); + String[] inputArr = equation.split(DELIMITER); + Arrays.stream(inputArr).filter(s -> !isParesInt(s)) + .forEach(s -> addSymbolList(symbolList, s)); + return symbolList; + } + + private boolean isParesInt(String input) { + return input.chars().allMatch(Character::isDigit); + } + + private void addNumList(List numList, String input) { + numList.add(Integer.parseInt(input)); + } + + private void addSymbolList(List symbolList, String input) { + checkSymbol(input); + symbolList.add(input); + } + + private void checkSymbol(String input) { + if (!SymbolStatus.checkSymbol(input)) { + throw new IllegalStateException(INVALID_CALCULATION_FORMAT); + } + } + + private void checkDoubleNumber(String[] split, int i) { + boolean parseInt = isParesInt(split[i]); + if (!parseInt) { + throw new IllegalStateException(INVALID_CALCULATION_FORMAT); + } + } + + private void checkDoubleSymbol(String[] split, int i) { + boolean parse = isParesInt(split[i]); + if (parse) { + throw new IllegalStateException(INVALID_CALCULATION_FORMAT); + } + } + +} diff --git a/src/main/java/study/InputView.java b/src/main/java/study/InputView.java new file mode 100644 index 0000000..00cbce9 --- /dev/null +++ b/src/main/java/study/InputView.java @@ -0,0 +1,16 @@ +package study; + +import java.util.Scanner; + +public class InputView { + + private Scanner scanner; + + public InputView(Scanner scanner) { + this.scanner = scanner; + } + + public String readEquation() { + return scanner.nextLine(); + } +} diff --git a/src/main/java/study/Main.java b/src/main/java/study/Main.java new file mode 100644 index 0000000..8a0d3fc --- /dev/null +++ b/src/main/java/study/Main.java @@ -0,0 +1,20 @@ +package study; + +import java.util.Scanner; + +public class Main { + + public static void main(String[] args) { + ResultView resultView = new ResultView(); + + resultView.initStart(); + Scanner scanner = new Scanner(System.in); + InputView inputView = new InputView(scanner); + + Equation equation = new Equation(inputView.readEquation()); + SimpleCalculator simpleCalculator = new SimpleCalculator(equation); + + resultView.viewResult(simpleCalculator); + + } +} diff --git a/src/main/java/study/ResultView.java b/src/main/java/study/ResultView.java new file mode 100644 index 0000000..34e38b1 --- /dev/null +++ b/src/main/java/study/ResultView.java @@ -0,0 +1,13 @@ +package study; + +public class ResultView { + + public void initStart() { + System.out.println("계산식을 입력하세요."); + } + + public void viewResult(SimpleCalculator simpleCalculator) { + int result = simpleCalculator.calEquation(); + System.out.println("계산 결과 = " + result); + } +} diff --git a/src/main/java/study/SimpleCalculator.java b/src/main/java/study/SimpleCalculator.java new file mode 100644 index 0000000..da1c80b --- /dev/null +++ b/src/main/java/study/SimpleCalculator.java @@ -0,0 +1,52 @@ +package study; + +public class SimpleCalculator { + + private final Equation equation; + + private static final String NO_DIVIDE_BY_ZERO = "0으로 나눌 수 없습니다."; + + public SimpleCalculator(Equation equation) { + this.equation = equation; + } + + public int cal(String symbol, Integer num1, Integer num2) { + if (symbol.equals(SymbolStatus.PLUS.toString())) { + return num1 + num2; + } + + if (symbol.equals(SymbolStatus.MINUS.toString())) { + return num1 - num2; + } + + if (symbol.equals(SymbolStatus.MULTIPLY.toString())) { + return num1 * num2; + } + + if (symbol.equals(SymbolStatus.DIVISION.toString())) { + checkDivideByZero(num2); + return num1 / num2; + } + + throw new IllegalStateException("잘못 입력하셨습니다.."); + } + + private void checkDivideByZero(Integer num) { + if (num == 0) { + throw new ArithmeticException(NO_DIVIDE_BY_ZERO); + } + } + + public int calEquation() { + int cal = cal( + equation.getSymbolsList().get(0), + equation.getNumbers().get(0), + equation.getNumbers().get(1)); + + for (int i = 1; i < equation.getSymbolsList().size(); i++) { + cal = cal(equation.getSymbolsList().get(i), cal, equation.getNumbers().get(i + 1)); + } + + return cal; + } +} diff --git a/src/main/java/study/SymbolStatus.java b/src/main/java/study/SymbolStatus.java new file mode 100644 index 0000000..a9a8654 --- /dev/null +++ b/src/main/java/study/SymbolStatus.java @@ -0,0 +1,21 @@ +package study; + +import java.util.Arrays; + +public enum SymbolStatus { + PLUS("+"), MINUS("-"), MULTIPLY("*"), DIVISION("/"); + + private String value; + + SymbolStatus(String value) { + this.value = value; + } + + public String toString() { + return this.value; + } + + public static boolean checkSymbol(String inputArr) { + return Arrays.stream(values()).anyMatch(value -> value.toString().equals(inputArr)); + } +} diff --git a/src/test/java/study/EquationTest.java b/src/test/java/study/EquationTest.java new file mode 100644 index 0000000..d9445e6 --- /dev/null +++ b/src/test/java/study/EquationTest.java @@ -0,0 +1,41 @@ +package study; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class EquationTest { + + @ParameterizedTest + @ValueSource(strings = {"/", "+"}) + @DisplayName("연산 기호만 반환") + void returnSymbolList(String symbol) { + //given + String input = "3 / 4 + 5"; + Equation equation = new Equation(input); + + //when + List symbols = equation.getSymbolsList(); + + //then + assertThat(symbols.contains(symbol)).isTrue(); + } + + @ParameterizedTest + @ValueSource(ints = {3, 4}) + @DisplayName("숫자들만 반환") + void returnIntList(int num) { + //given + String input = "3 + 4"; + Equation equation = new Equation(input); + + //when + List ints = equation.getNumbers(); + + //then + assertThat(ints.contains(num)).isTrue(); + } +} diff --git a/src/test/java/study/SimpleCalculatorTest.java b/src/test/java/study/SimpleCalculatorTest.java new file mode 100644 index 0000000..6695afb --- /dev/null +++ b/src/test/java/study/SimpleCalculatorTest.java @@ -0,0 +1,75 @@ +package study; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +public class SimpleCalculatorTest { + + @Test + void plusTest() { + //given + String input = "10 + 5"; + Equation equation = new Equation(input); + SimpleCalculator calculator = new SimpleCalculator(equation); + + //when + int result = calculator.cal( + equation.getSymbolsList().get(0), + equation.getNumbers().get(0), + equation.getNumbers().get(1)); + + //then + assertThat(result).isEqualTo(15); + } + + @Test + void minusTest() { + //given + String input = "10 - 5"; + Equation equation = new Equation(input); + SimpleCalculator calculator = new SimpleCalculator(equation); + + //when + int result = calculator.cal( + equation.getSymbolsList().get(0), + equation.getNumbers().get(0), + equation.getNumbers().get(1)); + + //then + assertThat(result).isEqualTo(5); + } + + @Test + void multiplyTest() { + //given + String input = "10 * 5"; + Equation equation = new Equation(input); + SimpleCalculator calculator = new SimpleCalculator(equation); + //when + int result = calculator.cal( + equation.getSymbolsList().get(0), + equation.getNumbers().get(0), + equation.getNumbers().get(1)); + + //then + assertThat(result).isEqualTo(50); + } + + @Test + void divisionTest() { + //given + String input = "10 / 5"; + Equation equation = new Equation(input); + SimpleCalculator calculator = new SimpleCalculator(equation); + //when + int result = calculator.cal( + equation.getSymbolsList().get(0), + equation.getNumbers().get(0), + equation.getNumbers().get(1)); + + //then + assertThat(result).isEqualTo(2); + } + +}