문제
해결 방안 고민
•
꺽새가 포함되지 않은 단어들은 쉽게 구현 가능하였으나 꺽새가 포함된 단어를 어떻게 처리할지가 문제였다.
•
단어를 뒤집어서 출력해야 하기 때문에 처음에는 reverse()를 활용할까 고민했다.
•
문득 괄호 관련 문제들은 자료구조 중에 Stack이나 Queue를 활용하여 풀이했던 경험을 떠올렸고 후입선출인 Stack이 문자열을 뒤집어 출력하기 좋다는 결론을 내렸다.
•
하지만 Stack만으로는 꺽새의 열고 닫음을 구분할 수 있는 방법이 없었고 한참을 고민하던 끝에 boolean 변수를 활용하여 꺽새의 열고 닫음을 구분하기로 하였다.
S가 주어진다 -> 단어만 뒤집으려고 한다
문자열 구성
- 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로만 이루어져 있다.
- 문자열의 시작과 끝은 공백이 아니다.
- '<' 와 '>' 가 문자열에 있는 경우 번갈아가면서 등장하며, '<'이 먼저 등장한다. 또, 두 문자의 개수는 같다.
- 태그는 '<'로 시작해서 '>'로 끝나는 길이가 3 이상인 부분 문자열이고, '<'와 '>' 사이에는 알파벳 소문자와 공백만 있다.
- 태그가 있으면 3이상, 태그 사이에는 알파벳 소문자와 공백만 있음
- 단어는 알파벳 소문자와 숫자로 이루어진 부분 문자열
- 연속하는 두 단어는 공백 하나로 구분
- 태그와 단어 사이에는 공백이 없음 => html 문법과 동일
- 태그 안의 단어는 뒤집어서 출력하지 않고 그대로 출력(공백도 그대로 유지)
Markdown
복사
해결 방법
•
StringBuilder를 활용하여 시간 단축을 한다.
•
꺽새가 포함되지 않은 문자열은 그대로 출력하면 된다.
•
문자열을 뒤집어서 출력해야 하므로 Stack 자료구조를 활용한다.
•
flag의 true, false를 활용하여 조건에 따라 stack을 활용하는 게 포인트다.
코드
package algo250211;
import java.io.*;
import java.util.*;
// 단어 뒤집기 2 - 실버 3
// 공백을 기준으로 단어를 나눈다
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
String str = br.readLine();
boolean flag = false; // 열린 꺽새, 닫힌 꺽새 판별 위한 flag
// 후입 선출 위한 Stack 활용
Stack<Character> stack = new Stack<>();
// 문자열 길이 만큼 반복문 수행
int length = str.length();
for (int i = 0; i < length; i++) {
// 열린 꺽새를 만났다면, stack이 비어있지 않을 경우 모든 원소를 꺼내고 flag를 true로 변환
if (str.charAt(i) == '<') {
while (!stack.isEmpty()) {
sb.append(stack.pop());
}
flag = true;
} else if (str.charAt(i) == '>') { // 닫힌 꺽새를 만났을 경우, flag를 false로 입력 후 '>' 저장
flag = false;
sb.append(str.charAt(i));
continue;
}
// flag가 true인 경우, '>'를 만나기 전까지 그대로 입력
if (flag == true) {
sb.append(str.charAt(i));
} else { // false 인 경우, 괄호 이외의 문자 처리
// 해당 인덱스의 i번째 문자가 공백인 경우, 모든 원소를 pop하고 공백 추가
if (str.charAt(i) == ' ') {
while (!stack.isEmpty()) {
sb.append(stack.pop());
}
sb.append(' ');
continue;
} else {
// 그 외, stack에 문자 추가
stack.push(str.charAt(i));
}
}
// 반복문이 마지막 횟수일 때, 스택이 비어있지 않으면 원소 추가하기
if (i == length - 1) {
while (!stack.isEmpty()) {
sb.append(stack.pop());
}
}
}
System.out.print(sb);
}
}
Java
복사