본문 바로가기
Problem Solving/백준

[백준] 17413번 : 단어 뒤집기 2

by shinbian11 2020. 8. 27.

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

 

17413번: 단어 뒤집기 2

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

www.acmicpc.net


//c++

#include <bits/stdc++.h>
#define F_I ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

using namespace std;
typedef long long ll;
stack<char> s;
void print(stack<char>& s)
{
	while (!s.empty())
	{
		cout << s.top();
		s.pop();
	}
	return;
}
int main()
{
	F_I;
    
	string str;
	bool tag = false;
	getline(cin, str);
    
	str += '\n';
    
	for (char ch : str)
	{
		if (ch == '<')
		{
			print(s);
			tag = true;
			cout << ch;
		}
		else if (ch == '>')
		{
			tag = false;
			cout << ch;
		}
		else if (tag == false) //ch가 <도 아니고 > 도 아니지만, tag가 false인 경우
		{
			if (ch == ' ' || ch =='\n')
			{
				print(s);
				cout << ch;
			}
			else
				s.push(ch);
		}
		else if (tag == true)  //ch가 <도 아니고 > 도 아니지만, tag가 true인 경우
		{
			cout << ch;
		}
	}
}

 

▶ tag 안에 들어있는 문자열과, tag 안에 들어있지 않는 문자열을 구분하기 위해, tag 라는 변수를 따로 선언하여,

tag 안쪽에서는 tag 라는 변수를 true로 하게 바꾸었고, tag 밖에서는 tag 라는 변수를 false로 바꾸었다.

 

 < 이 나오는 순간 tag의 시작이므로, < 전에 있었던 문자열을 모두 출력해준다.

-> 물론 이 문자열이 빈 문자열일수도 있고 (<가 문장의 처음이라면) (ex. <abc fdc>  )

-> abc와 같은 일반 문자열 일수도 있다. (<가 오기 전에 그 바깥에서 어떤 문자열이 나오다가 중간에 <가 나온 경우라면) (ex. abc<fdc> )

 

어쨌든 그 문자열을 모두 출력해주는(거꾸로 출력해야됨! 왜냐하면 tag 바깥의 문자열일테니까) 함수인 print() 함수를 실행 한 뒤, 이때 부터는 tag 안쪽이므로 tag 변수를 true로 바꾸어준다.

 

▶ > 이 나오는 순간이 tag의 끝이므로, 이때 tag 변수를 다시 false로 바꾸어 준 다음, ch인 >를 출력해준다.

 

tag == true 인 경우는 stack에 따로 담지 않고 바로 바로 출력한다. 왜냐하면 문제에서 tag 안쪽에 있는 문자들은 거꾸로 출력하지 말고 그냥 바로 출력하라고 나와있기 때문이다.

 

하지만 tag == false 인 경우에는 tag 바깥 쪽의 문자들이라는 의미이므로, 이땐 바로 출력하지 말고 스택에 담아두어야 한다. (그래야 나중에 print() 함수를 통해 문자열을 거꾸로 출력할 수 있으니까)

 

그런데 만약 tag 바깥에서 띄어쓰기 줄 바꿈 문자가 나온다면 그것 또한 역시 print() 함수를 이용하여 스택에 들어있는 문자들을 거꾸로 출력을 해줘야 하므로, 다시 한번 if ~else 문을 사용하여 두 가지 경우로 나눈다.