17413

NJW·2022년 5월 1일
0

코테

목록 보기
108/170

들어가는 말

저번에 풀었던 단어 뒤집기와 유사한 문제다. 그러나 괄호에 있는 문자는 tag로 지정해 뒤집기를 하지 않는다는 점에서 복잡해졌다.

처음에는 tag에 있는 단어만을 떼서 출력해주고 그 나머지를 stack에 넣는 방식을 사용했다. 그러나 이 방식은 너무 복잡해서 풀기가 어려웠다. 다른 사람의 풀이를 찾아봤는데, tag일 경우 bool형식을 true로 두는 방식이 굉장히 간편해 보였다. 즉, tag가 시작할 때 stack에 있는 문자를 모두 빼주고(처음 풀이에서는 이 부분에서 어려움을 겪었다) b를 true로 돌려준다. 만일 tag가 끝이 났다면 b를 false로 만든다. b가 true일 때만 s[i]를 그냥 출력해 주는데 이렇게 하면 따로 while을 안 써도 되서 편리하다.
그리고 띄어쓰기와 '\n'(문장이 끝에 '\n'을 붙여줘서 끝을 표시했다)일 때는 stack을 돌리고 단어가 끝나는 경우 띄어쓰기를 출력해준다.
만일 위의 경우에 다 해당하지 않는 단어이면 stack에 push해준다.

코드 설명

주석참고

코드

#include<iostream>
#include<string>
#include<stack>

using namespace std;

int main() {
	string s = "";
	stack<char> st;
	/*b가 true라면 tag라는 뜻이다.*/
	bool b = false;

	getline(cin, s);

	/*문장이 끝났음을 암시. 만일 없을 경우 마지막 단어를 무시할 수 있다.*/
	s += '\n';

	/*총 세 가지로 생각한다.
	1. tag바로 옆에 붙어 있는 단어
	2. tag안에 있는 단어
	3. 띄어쓰기가 존재하는 단어*/
	for (int i = 0; i < s.length(); i++) {
		/*1. tag바로 옆에 붙어있는 단어
		만일 s[i]가 <이라면 tag가 시작된다는 뜻이니 tag바로 앞에 있는 단어를 출력해야 한다.
		그리고 tag가 시작되었음을 알리는 b를 true로 돌려준다.*/
		if (s[i] == '<') {
			while (!st.empty()) {
				cout << st.top();
				st.pop();
			}
			cout << "<";
			b = true;
		}
		/*tag가 끝났으니 b를 false를 돌려준다.*/
		else if (s[i] == '>') {
			cout << ">";
			b = false;
		}
		/*만일 tag가 진행중이라면(b가 true라면) s[i]를 그냥 출력한다.*/
		else if (b) {
			cout << s[i];
		}
		/*만일 tag가 시작되는 문자에 붙어있는 단어가 아니고 띄어쓰기로 이루어진 단어 혹은 단어가 끝이 났다면 stack에 있는 단어들을 출력한다.
		그리고 st가 비었다면 이는 단어가 끝이 났다는 의미니까 띄어쓰기를 출력한다.*/
		else if (s[i] == ' ' || s[i] == '\n') {
			while (!st.empty()) {
				cout << st.top();
				st.pop();
			}
			cout << ' ';
		}
		/*만일 '<'나 ' '에 붙어있지 않다면 그냥 stack에 넣어준다.*/
		else {
			st.push(s[i]);
		}

	}
}
profile
https://jiwonna52.tistory.com/

0개의 댓글