문제
문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다.
먼저, 문자열 S는 아래와과 같은 규칙을 지킨다.
- 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로만 이루어져 있다.
- 문자열의 시작과 끝은 공백이 아니다.
- '<'와 '>'가 문자열에 있는 경우 번갈아가면서 등장하며, '<'이 먼저 등장한다. 또, 두 문자의 개수는 같다.
태그는 '<'로 시작해서 '>'로 끝나는 길이가 3 이상인 부분 문자열이고, '<'와 '>' 사이에는 알파벳 소문자와 공백만 있다. 단어는 알파벳 소문자와 숫자로 이루어진 부분 문자열이고, 연속하는 두 단어는 공백 하나로 구분한다. 태그는 단어가 아니며, 태그와 단어 사이에는 공백이 없다.
입력
첫째 줄에 문자열 S가 주어진다. S의 길이는 100,000 이하이다.
출력
첫째 줄에 문자열 S의 단어를 뒤집어서 출력한다.
접근 방식
분명 간단했으나.. 귀찮은 문제였다..
처음에는 공백을 기준으로 문자열을 나눠서 처리하려고 했으나
그렇게 하니 태그 안에 공백이 있을 경우 처리가 복잡해졌다.
따라서 모든 문자를 받아서 처리하는 식으로 변경하였다.
이 때,
1. < 문자일 경우 태그의 시작을 알리기 때문에 isTag 플래그를 통해 현재 문자열이 태그임을 나타내준다.
하지만, 이 때 <과 붙어있으면서 태그 안에 들어가지 않는 문자일 경우 단어를 뒤집어서 출력해야 하기 때문에
만약 스택이 비어있지 않다면 문자를 먼저 출력해야 한다
2. > 문자일 경우 현재까지 문자가 태그 내의 문자임을 나타내기 때문에
스택 안에 문자들을 다시 순서대로 정렬해 출력해준다.
또한 isTag 플래그를 다시 false로 처리해준다.
3. 일반 문자일 경우
3-1. 만약 문자가 공백이라면 공백이전의 문자가 태그인지 확인 후, 태그가 아니면 뒤집어서 출력해준다.
3-2. 공백이 아니라면 스택에 넣어준다
복잡하지만 순서대로 생각해본다면 간단한 문제이다
코드
#include<bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false); cin.tie(0);
string str;
getline(cin, str);
stack<char> st;
bool isTag = false;
for(auto c : str ) {
if(c == '<') {
while(!st.empty()) {
cout<<st.top();
st.pop();
}
st.push(c);
isTag = true;
}
else if(c == '>') {
st.push(c);
string tmp;
while(!st.empty()) {
tmp = st.top() + tmp;
st.pop();
}
cout<<tmp;
isTag = false;
}else {
if(c == ' ' && !isTag) {
while(!st.empty()) {
cout<<st.top();
st.pop();
}
cout<<" ";
}
else st.push(c);
}
}
while(!st.empty()) {
cout<<st.top();
st.pop();
}
}
'Algorithm' 카테고리의 다른 글
[BOJ] 소수 2581번 C++ (0) | 2024.11.13 |
---|---|
[BOJ] 원상 복구 (small) 22858번 C++ (0) | 2024.11.09 |
[BOJ] 빙고 2578번 C++ (0) | 2024.11.05 |
[BOJ] 기적의 매매법 20546번 C++ (0) | 2024.10.31 |
[BOJ] 트리 1068번 C++ (0) | 2024.10.31 |