문제 설명
문자열 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));
}
}
'연습 코딩테스트' 카테고리의 다른 글
연습문제 2-3(5) 마지막에 남는 사람의 번호 구하기 (0) | 2023.04.06 |
---|---|
연습문제 2-3(4) 뒤집어야 하는 비트의 개수 (0) | 2023.04.06 |
연습문제 2-3(2) 잘못된 출석부 번호 반환 (0) | 2023.04.06 |
연습문제 2-3(1) s에 포함된 횟수가 많은 순서대로 적힌 문자열 반환 (0) | 2023.04.06 |
연습문제 2-2(5) 정수 자릿수를 거꾸로 뒤집기 (0) | 2023.04.06 |