BOJ 17413. 단어 뒤집기 2

Polynomeer·2020년 4월 7일
0

Baekjoon Online Judge

목록 보기
12/20
post-thumbnail

BOJ 17413. 단어 뒤집기 2

문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다.
먼저, 문자열 S는 아래와과 같은 규칙을 지킨다.

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

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

1. 문제 해석

• 알파벳 소문자, 숫자, 공백, 특수 문자(<, >)로 이루어진 문자열 S에서 단어를 뒤집는 문제
• 태그: <로 시작해서 >로 끝나는 문자열, 사이에는 알파벳 소문자와 공백만 있음
• 단어: 알파벳 소문자와 숫자로만 이루어짐
• 단어와 단어 사이에는 공백 한 칸, 단어와 태그 사이에는 공백이 없음
<open>tag<close> → <open>gat<close>
<ab cd>ef gh<ij kl> → <ab cd>fe hg<ij kl>

단어뒤집기와 비슷하게 풀 수 있다.
• 태그 안인지 밖인지 구분해서 뒤집을지 말지 결정해야 한다. (태그 안->그대로, 태그 밖->뒤집기)

2. 문제 풀이

이 문제를 풀기위해서 모든 경우를 생각하면서 순서대로 코드를 작성하면 된다. 그리고 앞서 말한 조건을 체크 해주면서 처리해준다.

  • 열린 태그(<)가 나오면 처음 시작이거나, 태그 안쪽 문자열의 끝이다.
  • 닫힌 태그(>)가 나오면 마지막이거나, 태그 안쪽 문자열의 시작이다.
  • 태그 안쪽/바깥쪽을 구분하여 안쪽이면 그대로 출력하고, 바깥쪽이면 뒤집어 출력 하기위해 스택에 넣는다. 그리고 다시 열린 태그(<)가 나오면 스택에서 꺼내면서 출력한다.

좀 더 구체적으로 이 과정을 나열해보면 다음과 같다.

  • 한 문자씩 읽으면서 조건에 따라 처리한다. bool형 변수로 태그가 열렸는지 체크한다.
  • 열린 태그(<)가 나오면 열렸다고 표시하고 태그와 스택에 있는 값을 모두 꺼내어 출력한다.
    • 이때 처음시작인 경우에는 스택에 값이 없을 것이므로 아무것도 출력되지 않는다.
    • 스택에 값이 있다는 것은 태그 사이의 문자열이라는 뜻이므로 뒤집어 출력된다.
  • 닫힌 태그(>)가 나오면 닫혔다고 표시하고 그냥 태그만 출력한다.
  • 그냥 문자인 경우 단어뒤집기와 같이 공백이 나오면 스택을 모두 출력하고 아니면 스택에 넣는다.
#include <iostream>
#include <string>
#include <stack>
using namespace std;
void print(stack<char> &s) {	// 스택에 있는 값을 모두 출력
    while (!s.empty()) {
        cout << s.top();
        s.pop();
    }
}
int main() {
    string str;
    getline(cin, str);
    bool tag = false;
    stack<char> s;
    for (char ch : str) {	// 문자열에서 한 문자씩 꺼내며 반복
        if (ch == '<') {	// 여는 태그가 나오면
            print(s);		// 스택에 값들을 모두 출력하고 
            tag = true;		// 태그가 열렸다고 표시
            cout << ch;		// 태그 출력
        } else if (ch == '>') {	// 닫는 태그가 나오면
            tag = false;	// 태그가 닫혔다고 표시
            cout << ch;		// 태그 출력
        } else if (tag) {	// 태그가 열린상태라면
            cout << ch;		// 문자 '그대로' 출력
        } else {		// 태그가 닫힌상태라면
            if (ch == ' ') {	// 공백이 나오면
                print(s);	// 스택을 모두 출력
                cout << ch;	// 공백도 출력
            } else {		// 공백이 나오기 전까지는
                s.push(ch);	// 스택에 삽입
            }
        }
    }
    print(s);	// 스택에 남은게 있다면 모두 출력
    cout << '\n';
    return 0;
}
profile
어려운 문제를 어렵지 않게.

0개의 댓글