문제 설명

문자열 S는 숫자와 사칙연산 기호(+, -, *, /)로 이루어진 수식입니다.

해당 수식을 사칙연산 계산 순서에 맞춰 계산하는 프로그램을 작성하세요.

단, 결과는 소수점 자리는 2번째 자리까지 표현합니다. 즉, 소수점 자리 3번째 자리에서 내림하여 실수(double) 형식으로 출력하세요.


입력 형식

· S : 숫자와 사칙연산으로 이루어진 문자열


출력 형식

· S 수식을 계산한 결과를 double로 반환


제약 사항

· 1 <= S <= 100


입출력 예시

· 예시1

  · 입력

      · S = "2*3+5/6*3+15"

  · 출력 : 23.50

  · 설명 : 곱셈과 나눗셈을 먼저 계산하면, 그 결과 23.50이 된다.

 

· 예시2

    · 입력

      · S = "10/3"

  · 출력 : 3.33

  · 설명 : 10을 3으로 나누면 3.3333....이다. 소수점 3번째 자리에서 버림 할 경우 출력은 3.33이 된다.


작성 코드

import java.util.Stack;

class Solution233 {
    public double solution(String S) {
        // Double 타입의 값을 저장할 수 있는 스택(stack)을 선언
        Stack<Double> stack = new Stack<>();
        double num = 0;
        char prevOp = '+';

        for (int i = 0; i < S.length(); i++) {
            char c = S.charAt(i);

            // 가져온 문자가 숫자인 경우,
            // 현재 숫자 변수(num)에 추가하여 계속 더해나감
            // isDigit : 주어진 문자가 10진수(0~9)인지 여부 판별하는 메소드
            if (Character.isDigit(c)) {
                num = num * 10 + (c - '0');
                // '0'의 아스키 코드 값은 48
                // 문자열 10이 주어질 때
                // num = num * 10 + ('1' - '0'); -> num = 1
                // num = num * 10 + ('0' - '0'); -> num = 10
            }

            // 숫자가 아닌 경우, 또는 마지막 문자인 경우 다음을 실행
            if (!Character.isDigit(c) || i == S.length() - 1) {
                if (prevOp == '+') {
                    stack.push(num);
                } else if (prevOp == '-') {
                    stack.push(-num);
                } else if (prevOp == '*') {
                    double temp = stack.pop();
                    stack.push(temp * num);
                } else if (prevOp == '/') {
                    double temp = stack.pop();
                    stack.push(temp / num);
                }

                prevOp = c;
                num = 0;
            }
        }

        double result = 0;
        while (!stack.isEmpty()) {
            result += stack.pop();
        }
        return Math.round(result * 100) / 100.0;
        // 소수점 둘째자리까지 반올림하여 반환
        }

    public static void main(String[] args) {
        Solution233 st = new Solution233();
        String s = "2*3+5/6*3+15";
        System.out.println(st.solution(s));
        String s2 = "10/3";
        System.out.println(st.solution(s2));
    }
}

 

정답 코드

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

class Solution {
    public double solution(String S) {
        Pattern numPattern = Pattern.compile("([0-9]+)");
        Matcher numMatcher = numPattern.matcher(S);
        List<Integer> numbers = new ArrayList<>();

        while (numMatcher.find()) {
            numbers.add(Integer.parseInt(numMatcher.group()));
        }

        Pattern opPattern = Pattern.compile("([+\\-*/])");
        Matcher opMatcher = opPattern.matcher(S);
        List<Character> operators = new ArrayList<>();

        while (opMatcher.find()) {
            operators.add(opMatcher.group().charAt(0));
        }

        double temp = numbers.get(0);
        double result = 0;

        for (int i = 0; i < operators.size(); i++) {
            if (operators.get(i) == '*') {
                temp *= (double)numbers.get(i+1);
            } else if (operators.get(i) == '/') {
                temp /= (double)numbers.get(i+1);
            } else if (operators.get(i) == '+') {
                result += temp;
                temp = (double)numbers.get(i+1);
            } else if (operators.get(i) == '-') {
                result += temp;
                temp = -(double)numbers.get(i+1);
            }
        }
        result += temp;
        return Math.floor(result * 100) / 100.0;
    }

    public static void main(String[] args) {
        Solution st = new Solution();
        String s = "2*3+5/6*3+15";
        System.out.println(st.solution(s));
        String s2 = "10/3";
        System.out.println(st.solution(s2));
    }
}