문제: https://school.programmers.co.kr/learn/courses/30/lessons/17682
1. 코드
import java.util.*;
class Solution {
public int solution(String dartResult) {
int answer = 0;
Stack <Integer> stack = new Stack<>();
String[] s1 = dartResult.split("[^0-9]+"); //문자 사이에 있는 숫자로만 구성
String[] s2 = dartResult.split("[0-9]+"); //숫자 사이에 있는 문자로만 구성
for(int i = 0; i < s1.length; i++) {
int num = Integer.parseInt(s1[i]);
int index = i + 1; //첫번째 문자열은 공백이기에 제외
while(!s2[index].isBlank()) {
if(s2[index].matches("S(.*)"))
stack.push(num);
else if(s2[index].matches("D(.*)")) {
num *= num;
stack.push(num);
}
else if(s2[index].matches("T(.*)")) {
num *= num * num;
stack.push(num);
}
else if(s2[index].matches("#(.*)")) {
stack.push(stack.pop() * -1);
}
else { //스타상(*)일 때
if(stack.size() >= 2) { //이미 두 개 이상의 점수를 획득했을 때
int temp1 = stack.pop() * 2;
int temp2 = stack.pop() * 2;
stack.push(temp2);
stack.push(temp1);
}
else //획득한 점수가 1개일 때
stack.push(stack.pop() * 2);
}
s2[index] = s2[index].substring(1); //첫 번째 문자 제거
}
}
while(!stack.isEmpty()) //계산 결과 전부 더하기
answer += stack.pop();
return answer;
}
}
2. 설명
int answer = 0;
Stack <Integer> stack = new Stack<>();
String[] s1 = dartResult.split("[^0-9]+"); //문자 사이에 있는 숫자로만 구성
String[] s2 = dartResult.split("[0-9]+"); //숫자 사이에 있는 문자로만 구성
이 문제는 스택을 이용한다면 조금 쉽게 해결할 수 있습니다. split() 메서드는 matches() 메서드와 마찬가지로 정규식으로 처리가 가능하기에 s1은 문자들을 기준으로 숫자들을 추출하고 s2는 숫자들을 기준으로 문자들을 추출합니다.
for(int i = 0; i < s1.length; i++) {
int num = Integer.parseInt(s1[i]);
int index = i + 1; //첫번째 문자열은 공백이기에 제외
s2의 경우 숫자로 구분하여서 첫 번째 숫자를 기준으로 좌우로 추출되어 공백이 추가로 추출되기에 제일 처음에는 공백이 추출되므로 공백을 제외하기 위해서 i + 1을 index에 저장하여 index는 s2의 인덱스 값입니다. 문자열로 추출했기에 활용할 문자열의 길이는 s1와 s2가 동일합니다.
while(!s2[index].isBlank()) {
if(s2[index].matches("S(.*)"))
stack.push(num);
else if(s2[index].matches("D(.*)")) {
num *= num;
stack.push(num);
}
else if(s2[index].matches("T(.*)")) {
num *= num * num;
stack.push(num);
}
else if(s2[index].matches("#(.*)")) {
stack.push(stack.pop() * -1);
}
else { //스타상(*)일 때
if(stack.size() >= 2) { //이미 두 개 이상의 점수를 획득했을 때
int temp1 = stack.pop() * 2;
int temp2 = stack.pop() * 2;
stack.push(temp2);
stack.push(temp1);
}
else //획득한 점수가 1개일 때
stack.push(stack.pop() * 2);
}
s2[index] = s2[index].substring(1); //첫 번째 문자 제거
}
문자가 S, D, T가 나오면 즉시 Stack에 값을 push하여 스타상(*)과 아차상(#)일 때는 Stack의 값을 pop한 뒤 처리하여 다시 push해줍니다. 문자에 적절한 처리가 되었다면 s2의 인덱스의 문자열에서 첫 번째 문자를 없애주며 문자열이 없어질 때까지 반복해 줍니다.
while(!stack.isEmpty()) //계산 결과 전부 더하기
answer += stack.pop();
모든 과정이 마무리되면 Stack에 저장된 값들을 전부 더해주면 문제는 해결됩니다.
3. 정리
- split() 메서드와 정규식을 활용하여 문자와 숫자를 구분
- Stack을 활용하여 계산 결과를 임시로 저장
- 두 글자 이상의 문자열에서 정규식 주의(예: s2.matches("S")은 "S"에서는 true, "S*"에서 false로 반환하기에 s2.matches("S(.*)")은 "S*"와 "S" 모두 true 반환)
출처: 프로그래머스 코딩 테스트 연습,
https://school.programmers.co.kr/learn/challenges
'컴퓨터 > 프로그래머스' 카테고리의 다른 글
프로그래머스 - 131128번: 숫자 짝궁 [Java] (0) | 2023.08.04 |
---|---|
프로그래머스 - 77484번: 로또의 최고 순위와 최저 순위 [Java] (0) | 2023.08.03 |
프로그래머스 - 136798번: 기사단원의 무기 [Java] (0) | 2023.08.01 |
프로그래머스 - 161989번: 덧칠하기 [Java] (0) | 2023.07.31 |
프로그래머스 - 42889번: 실패율 [Java] (0) | 2023.07.30 |