티스토리 뷰

728x90

문제 링크

문제 설명

문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다.

먼저, 문자열 S는 아래와과 같은 규칙을 지킨다.

  1. 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로만 이루어져 있다.
  2. 문자열의 시작과 끝은 공백이 아니다.
  3. '<'와 '>'가 문자열에 있는 경우 번갈아가면서 등장하며, '<'이 먼저 등장한다. 또, 두 문자의 개수는 같다.

태그는 '<'로 시작해서 '>'로 끝나는 길이가 3 이상인 부분 문자열이고, '<'와 '>' 사이에는 알파벳 소문자와 공백만 있다. 단어는 알파벳 소문자와 숫자로 이루어진 부분 문자열이고, 연속하는 두 단어는 공백 하나로 구분한다. 태그는 단어가 아니며, 태그와 단어 사이에는 공백이 없다.

입력

첫째 줄에 문자열 S가 주어진다. S의 길이는 100,000 이하이다.

출력

첫째 줄에 문자열 S의 단어를 뒤집어서 출력한다.

 

문제 풀이 과정

이 문제는 단순하면서도 고려해야 할 조건들이 꽤 많은 편이다. 그래서 if 문을 많이 써서 코드가 깔끔하지 않아졌다.

키 포인트는 스택을 이용하면서 문자를 뒤집는다!

 

<> 이렇게 태그로 된 부분은 문자열이 뒤집히면 안되며 유지가 되어야 한다.

 

if(item == '>'){
    flag = false;
    tag.append(item);
    sb.append(tag);
    tag = new StringBuilder();
}
else if(item == '<' || flag){
    flag = true;
    tag.append(item);
}

 

이것을 코드로 나타낸 부분이다.

tag만 가지고 있는 별도의 변수를 만들어서 순서가 유지되도록 문자열을 하나씩 넣었다.

 

>닫기 표시가 나올 때는 tag의 문자열을 sb 문자열에 순서 유지한 상태로 그대로 넣어 주고, tag에 가지고있던 문자열을 초기화 시켜준다.

 

이제 공백일때를 보자.

공백일 때는 공백 앞에 있는 문자열이 뒤집힌다.

 

else if(item == ' '){
    while (!stack.isEmpty()){
        sb.append(stack.pop());
    }
    sb.append(" ");
}

 

공백 일때는 기존에 스택에 쌓아둔 문자들을 꺼내서 sb에 넣어 준다.

마지막으로 공백 처리도 해야되기 때문에 공백도 sb에 넣어 준다.

 

 

마지막으로 고려할 사항은 문자열 사이에 공백도 없고 바로 태그가 이어졌을 때이다.

이때는 뒤에 태그가 있는지 체크한 뒤 스택에 있는 문자를 꺼내면 된다.

 

else if (i + 1 < input.length() && input.charAt(i + 1) == '<') {
    sb.append(item);
    while (!stack.isEmpty()){
        sb.append(stack.pop());
    }
}

여기서 중요한 점은 현재 시점에서 뒤에 > 가 있는지 체크 하기 때문에 현재 문자를 어디에도 넣어 주지 않았다는 점이다.

이것을 스택에 넣은 다음 다시 스택에서 꺼내도 되지만, 이 문자를 스택에서 꺼내게 된다면 맨 처음에 해당 되는 문자이기 때문에 sb 에 먼저 넣어 주고 스택에 있는 문자를 꺼내 주었다.

else{
    stack.add(item);
}

위 조건들 모두 해당이 안되면 스택에 해당 문자를 넣어 주면 된다.

if(!stack.isEmpty()){
    while (!stack.isEmpty()){
        sb.append(stack.pop());
    }
}

 

모든 반복문을 빠져 나온 다음 스택에 어떤 값이 있다면 그 값을 꺼내주었다.

 

이렇게 한 이유는 위와 같은 상황일때 맨 마지막 단어 처리가 반복문 안에서 처리가 안되기 때문이다.

 

전체 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String input = br.readLine();

        Stack<Character> stack = new Stack<>();
        StringBuilder sb = new StringBuilder();
        StringBuilder tag = new StringBuilder();
        boolean flag = false;

        for(int i = 0; i < input.length(); i++){
            char item = input.charAt(i);
            if(item == '>'){
                flag = false;
                tag.append(item);
                sb.append(tag);
                tag = new StringBuilder();
            }
            else if(item == '<' || flag){
                flag = true;
                tag.append(item);
            }
            else if(item == ' '){
                while (!stack.isEmpty()){
                    sb.append(stack.pop());
                }
                sb.append(" ");
            }
            else if (i + 1 < input.length() && input.charAt(i + 1) == '<') {
                sb.append(item);
                while (!stack.isEmpty()){
                    sb.append(stack.pop());
                }
            }
            else{
                stack.add(item);
            }
        }

        if(!stack.isEmpty()){
            while (!stack.isEmpty()){
                sb.append(stack.pop());
            }
        }
        System.out.println(sb.toString());
    }
}
728x90