티스토리 뷰

알고리즘

[백준 17413번/c++] 단어 뒤집기 2

JeongeunChoi 2023. 1. 30. 14:52

문제

문자열 S는 태그와 단어를 포함한다. 이때 단어만 뒤집는다.

https://www.acmicpc.net/problem/17413

 

17413번: 단어 뒤집기 2

문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다. 먼저, 문자열 S는 아래와과 같은 규칙을 지킨다. 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로만 이루어져

www.acmicpc.net

조건

  • 문자열 S
    • 알파벳 소문자, 숫자, 공백(' '), 특수 문자('<', '>')로만 이루어진다.
    • 시작과 끝은 공백이 아니다.
    • '<'와 '>'가 문자열에 있는 경우 번갈아가면서 등장하며, '<'이 멈ㄴ저 등장한다. 두 문자의 개수는 같다.
  • 태그
    • '<'로 시작하여 '>'로 끝나는 길이가 3 이상인 부분 문자열
    • '<'와 '>' 사이에는 알파벳 소문자와 공백만 있다.
  • 단어
    • 알파벳 소문자와 숫자로 이루어진 부분 문자열
    • 연속하는 두 단어는 공백 하나로 구분한다.
  • 태그는 단어가 아니며, 태그와 단어 사이에는 공백이 없다.

 

입출력

입력

  • 문자열 S

출력

  • 문자열 S의 단어를 뒤집어서 출력

 


접근

태그와 단어를 구분하여 태그는 순서 그대로, 단어는 순서를 뒤집는다.

코드 구현

태그와 단어를 구분하기 위해

'<'와 '>'를 문자열에서 찾는다.

'<'와 '>'의 위치를 찾은 후

'<'부터 '>' 까지는 태그이므로 answer 문자열에 그대로 추가하고

그 밖의 것들은 순서를 바꾸어 추가한다.

 

✔️

이 때, 공백이 포함된 문자열의 경우

따로 함수를 만들어 공백을 기준으로 각 부분 문자열을 뒤집어주어야 한다.

 

 


성공 코드(내 코드)

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;

// 공백 문자를 포함하는 문자열 뒤집기
string reverse_str(string before_reverse){
    string after_reverse="";
    int s=0, e=before_reverse.size();
    for(int i=0; i<before_reverse.size(); i++){
        if(isspace(before_reverse[i])!=0){
            string temp=before_reverse.substr(s, i-s);
            reverse(temp.begin(), temp.end());
            s=i+1;
            after_reverse+=temp;
            after_reverse+=" ";
        }
    }
    string temp=before_reverse.substr(s, e-s);
    reverse(temp.begin(), temp.end());
    after_reverse+=temp;

    return after_reverse;
}

int main(){
    // freopen("input.txt", "rt", stdin);
    string answer;
    string str;
    size_t tag_start=0, tag_end=0;
    getline(cin, str);
    tag_start=str.find('<', tag_start);
    tag_end=str.find('>', tag_end);
    if(tag_start==string::npos){
        answer+=reverse_str(str);
    } else{
        if(tag_start>0){
            answer+=reverse_str(str.substr(0, tag_start));
        }
        while(1){
            if(tag_start==string::npos || tag_end==string::npos){
                break;
            }
            answer+=str.substr(tag_start, tag_end+1-tag_start);
            tag_start=str.find('<', tag_start+1);
            answer+=reverse_str(str.substr(tag_end+1, tag_start-(tag_end+1)));
            tag_end=str.find('>', tag_end+1);
        }
    }
    cout << answer;

    return 0;
}

 

 


후기

문제 접근 후 '<'와 '>'의 인덱스 처리하는 부분과 공백이 포함된 부분 문자열을 뒤집는 부분이 코드 구현에 있어 중요한 포인트인 것 같다.