coding test/백준 맞은 문제들

[17413] 단어 뒤집기 2

로봇0301 2022. 11. 10. 22:31
 

단어 뒤집기 2 성공

시간 제한메모리 제한제출정답맞힌 사람정답 비율
1 초 512 MB 19070 10765 8290 56.680%

문제

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

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

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

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

입력

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

출력

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

예제 입력 1 

baekjoon online judge

예제 출력 1 

noojkeab enilno egduj

예제 입력 2 

<open>tag<close>

예제 출력 2 

<open>gat<close>

예제 입력 3 

<ab cd>ef gh<ij kl>

예제 출력 3 

<ab cd>fe hg<ij kl>

예제 입력 4 

one1 two2 three3 4fourr 5five 6six

예제 출력 4 

1eno 2owt 3eerht rruof4 evif5 xis6

예제 입력 5 

<int><max>2147483647<long long><max>9223372036854775807

예제 출력 5 

<int><max>7463847412<long long><max>7085774586302733229

예제 입력 6 

<problem>17413<is hardest>problem ever<end>

예제 출력 6 

<problem>31471<is hardest>melborp reve<end>

예제 입력 7 

<   space   >space space space<    spa   c e>

예제 출력 7 

<   space   >ecaps ecaps ecaps<    spa   c e>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include<iostream>
#include<stack>
#include<vector>
#include<string>
int main()
{
    std::string str;
    std::getline(std::cin, str);
    std::stack<char> stack;
    std::vector<char> sum;
 
    bool tag = false;
    bool space = false;
    for (auto _ch : str)
    {
        if (_ch == '<')
        {
            tag = true;
        }
        if (_ch == ' ')
        {
            space = true;
        }
 
        if (tag || space)
        {
            if (stack.size())
            {
                for (; stack.size() != 0;)
                {
                    sum.push_back(stack.top());
                    stack.pop();
                }
            }
            sum.push_back(_ch);
        }
        else
        {
            stack.push(_ch);
        }
 
        if (_ch == '>')
        {
            tag = false;
        }
 
        space = false;
    }
 
    for (; stack.size() != 0;)
    {
        sum.push_back(stack.top());
        stack.pop();
    }
 
    for (int i = 0; i < sum.size(); i++)
    {
        std::cout << sum[i];
    }
}
cs

sollution

코드가 어떻게 돌아가는지 설명하겠다.

 

반복문을 돌며 기본적으로는 문자들을 스택에 넣는다.

읽은 문자가 태그 혹은 공백이라면 스택에 넣지 않고. 만약 스택에 남아있는 게 있으면 한꺼번에 출력한다.

 

코드의 원리에 대해서 설명하겠다.

태그 혹은 공백으로 나뉘어진 글자 뭉치를 부르기 편하게 단어라고 하겠다.

 

스택에 넣었다 빼면 값의 순서는 뒤바뀐다.

그러나 우리는 단어끼리 뒤집어지는 것과 태그가 뒤집어지는 것을 원하지 않는다.

 

단어끼리 뒤집어지지 않게 하려면 단어끼리 따로따로 뒤집어줘야 한다.

태그를 뒤집어지지 않게 하려면 태그일 경우 뒤집지 않으면 된다.

 

읽은 문자가 태그이거나 공백이라면, 만약 바로 전에 있는 단어가 스택에 남아있다면, 바로 전에 있는 단어를 뒤집은 결과를 스택에서 빼내어 출력한 후. 읽은 문자는 스택에 넣지 않고 그대로 출력한다.