Study/Problem Solving
[백준 / Java] 1541번: 잃어버린 괄호 (실버2)
Pearlii
2023. 5. 23. 00:31
문제 풀이 날짜: 2023.05.22
포스트 작성일: 2023.05.23
* 학습 목적으로 작성하는 글입니다. 풀이가 정석적이지 못할 수도 있습니다.
문제 출처
백준 온라인 저지 1541번: 잃어버린 괄호 (실버2) (문제 링크)
키워드
그리디
풀이 접근법
- 식에 괄호를 여러 개 칠 수 있고, 하나의 괄호 안에 여러 개의 수가 들어갈 수 있다.
- (양수 + 어떤 수) 조합은 괄호를 쳐도 별 일이 일어나지 않는다.
- (음수 + 어떤 수) 조합에 괄호를 칠 때 주의가 필요하다.
- 괄호 안의 수는 모두 부호가 반대가 된다.
- 따라서 현재 가리키는 수가 양수라면 그냥 결과에 더해주고, 음수라면 적절한 연산을 한다.
- 괄호를 쳐야 하는 경우 : 뒤에 이어지는 수도 양수일 때
- 괄호를 치지 않아야 하는 경우 : 뒤에 이어지는 수가 음수일 때 (결괏값이 더 커진다)
- 반복문을 돌다가 음수를 만났다면…
- 음수를 만났을 때, 다음 수로 또 음수가 나올 때까지 양수들과 함께 괄호를 친다.
- 즉, 다음에 나오는 양수들은 무조건 부호를 뒤집어서 더해준다.
- 입력 String의 첫 번째 수부터 음수일 수도 있으니 처리에 주의하자.
코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String formula = br.readLine();
ArrayList<Integer> numbers = new ArrayList<>();
ArrayList<Character> operators = new ArrayList<>();
StringTokenizer st = new StringTokenizer(formula, "+-");
while(st.hasMoreTokens()) {
numbers.add(Integer.parseInt(st.nextToken()));
}
for(int i = 0; i < formula.length(); i++) {
char c = formula.charAt(i);
if(c == '+' || c == '-') {
operators.add(c);
}
}
int result = 0;
int numIdx = 0;
int opeIdx = 0;
//첫 번째로 더하는 수가 양수라면
if(numbers.size() != operators.size()) {
result += numbers.get(0);
numIdx = 1; //처리해주고 인덱스를 하나 증가시킨다.
}
int multiplier = 1;
while(numIdx < numbers.size() || opeIdx < operators.size()) {
if(operators.get(opeIdx) == '-') { //음수를 만났다면
multiplier = -1; //이 뒤로 괄호를 쳐서 음수로 만든다.
}
result += (numbers.get(numIdx) * multiplier);
numIdx++;
opeIdx++;
}
System.out.print(result);
}
}
괄호의 특성을 이용하면 어렵지 않게 풀 수 있는 그리디 문제이다. 만약 정말로 문자열 사이사이에 괄호를 치려고 하면 조금 위험해진다. (과거의 나라면 그렇게 풀었을 듯하다.) 적당한 덧셈 뺄셈으로만 해결이 가능하다.
git 링크
https://github.com/jinju9553/23-CodingTest/blob/main/week9/day1/Q1541.java