본문 바로가기
코딩테스트 준비/백준

[백준/BOJ][C++] 4949번 균형잡힌 세상

by 스테디코디스트 2023. 8. 21.
반응형

<문제 소개>


<소스 코드>

#include <iostream>
#include <string>
#include <vector>
#include <stack>
using namespace std;

int main()
{
	// 쓰레드 환경이 아닐때 버퍼를 분리하여 처리속도를 빠르게 해줌
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	vector<string> output;

	while(true)
	{
		string s;
		getline(cin, s); // 공백 포함 문자열 입력

		if (s == ".") break;

		stack<char> stk;

		bool isBalanced = true; // 균형유무

		for (int j = 0; j < s.size(); j++)
		{
			char curWord = s[j];

			if (curWord == '(' || curWord == '[')
			{
				// 왼쪽 괄호들은 스택에 추가
				stk.push(curWord);
			}

			if (curWord == ')')
			{
				if (stk.empty())
				{
					// 스택이 비어있는 경우 -> 불균형
					isBalanced = false;
					break;
				}
				else if (stk.top() != '(')
				{
					// 스택의 마지막 원소가 '(' 가 아닌 경우 -> 불균형
					isBalanced = false;
					break;					
				}
				else
				{
					// 스택의 마지막 원소가 '(' 인 경우 -> 맨 마지막 원소 '(' 삭제
					stk.pop();
				}
			}

			if (curWord == ']')
			{
				if (stk.empty())
				{
					// 스택이 비어있는 경우 -> 불균형
					isBalanced = false;
					break;
				}
				else if (stk.top() != '[')
				{
					// 스택의 마지막 원소가 '[' 가 아닌 경우 -> 불균형
					isBalanced = false;
					break;
				}
				else
				{
					// 스택의 마지막 원소가 '[' 인 경우 -> 맨 마지막 원소 '[' 삭제
					stk.pop();
				}
			}
		}

		if (isBalanced && stk.empty())
		{
			// 스택이 비어있고, isBalanced가 true인 경우
			// 균형을 이루고 있는 경우
			output.push_back("yes");
		}
		else
		{
			// 균형을 이루고 있지 않은 경우
			output.push_back("no");
		}
	}

	for (int i = 0; i < output.size(); i++)
	{
		cout << output[i] << "\n";
	}

	return 0;
}

<풀이과정>

1. 결과를 저장한 output 벡터를 선언

2. while 반복문을 돌면서 getline을 이용해 공백을 포함하여 문자열 s를 입력받는다.

3. 만약 문자열 s가 "." 이라면 반복을 종료한다.

4. 괄호들을 담을 스택 stk를 선언, 균형유무를 판단할 isBalanced를 true로 초기화시켜서 선언한다.

5. 입력받은 문자열 s를 돌면서 현재 문자를 curWord에 저장한 뒤 curWord에 따라 조건문을 진행한다.

6-1. curWord가 왼쪽 괄호인 '(' 나 '[' 인 경우에는 스택에 해당 괄호를 추가해준다.

6-2. curWord가 오른쪽 소괄호 ')' 인 경우 먼저 스택 stk가 비어있는지 확인하고 비어있다면 왼쪽 보다 먼저 오른쪽 괄호가 온 것이기에 불균형이다. 따라서 isBalanced를 false로 바꾸고 break를 이용해 반복문을 빠져나간다. 스택이 비어있지 않고,  top함수를 이용해 스택의 마지막 원소를 찾아 해당 원소가 왼쪽 소괄호 '(' 가 아닌 경우 대괄호를 소괄호로 닫은 경우이므로 불균형이다. 따라서 위와 같이 isBalanced를 false로 바꾸고 break를 이용해 반복문을 빠져나간다. 마지막으로 스택의 마지막 원소가 왼쪽 소괄호 '(' 인 경우 해당 왼쪽 소괄호를 pop을 이용해 스택에서 꺼내준다.

6-3. curWord가 오른쪽 대괄호 ']' 인 경우 오른쪽 소괄호와 괄호만 바꾸고 같은 과정을 반복한다.

7. 위의 반복이 끝난 뒤 isBalanced가 여전히 true이고, 스택이 비어 균형을 이루고 있는 경우라면 output 벡터에 "yes"를 추가해주고 이외의 균형을 이루지 않고 있는 경우에는 output에 "no"를 추가해준다.

8. while 반복문을 빠져나온 뒤 output의 모든 원소들을 출력해준다.


<코멘트>

cin만 사용해서 문자열을 입력받으면 공백은 문자열에 포함 안된다는 것을 까먹고 있었다.

그리고 공백을 포함해서 문자열을 입력받기 위한 getline이라는 함수도 까먹고 있었다..ㅋㅋ

그래도 이번 문제를 통해 까먹었던 것을 다시 상기해보는 기회가 되었다!


<제출결과>