Doby's Lab

[C++] 스택 사용할 때 유의할 점 (백준 한정) 본문

C++

[C++] 스택 사용할 때 유의할 점 (백준 한정)

도비(Doby) 2021. 10. 27. 21:13

백준 15094번 문자열 관련 문제를 풀다가 VS 컴파일러에서는 오류가 없지만 백준에서는 Segfault Error가 나서 문제점을 찾았었다. 전에도 이런 비슷한 문제를 풀다가 똑같은 오류가 났었는데 두 문제의 공통점이 있었다.

문자열 문제
스택을 이용하여 풀려했다

문자열은 문제가 없는 거 같아서 스택을 살펴보았다.

 

아래 코드는 VS 컴파일러에서는 문제가 없지만 백준에서 에러가 발생한다.

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

int main() {
	char idx[1001];
	cin.getline(idx, 1001, '\n');
	stack<char> s;
	for (int i = 0; i < 1001; i++) {
		if (idx[i] == 'U') {
			if (s.empty()) {
				//std::cout << "U";
				s.push(idx[i]);
			}
		}
		else if (!s.empty()) {
			if (idx[i] == 'C' && s.top() == 'U') {
				if (s.size() == 1) {
					// 마지막 C와 중복될 수 있어서
					//std::cout << "C";
					s.push(idx[i]);
				}
			}
			else if (idx[i] == 'P') {
				// 이 또한 마지막 C인데 P를 넣으면 안 되서
				// size도 조건에 추가한다.
				if (s.top() == 'C' && s.size() == 2) {
					//std::cout << "P";
					s.push(idx[i]);
				}
			}
			else if (idx[i] == 'C') {
				if (s.top() == 'P' && s.size() == 3) {
					//std::cout << "C";
					s.push(idx[i]);
				}
			}
		}
	}

	//std::cout << '\n' << s.size() << '\n';

	if (s.size() == 4) {
		std::cout << "I love UCPC";
	}
	else {
		std::cout << "I hate UCPC";
	}

	return 0;
}

C, P, C를 스택에 넣는 과정에서 오류가 발생한다.

왜냐하면 스택이 empty인 상태에서 top을 찾는 것은 VS에서는 그냥 넘어가지만 백준에서는 '스택이 텅 비었는데 top이 어딨냐?'라고 오류를 낸다.

 

그래서 스택을 사용할 때 스택 내 원소에 접근할 때는 조건을 더 꼼꼼하게 살펴줘야 한다.

다음 조건을 추가

else if (!s.empty()) {
			if (idx[i] == 'C' && s.top() == 'U') { // top 찾음
				...
			}
			else if (idx[i] == 'P') {
				if (s.top() == 'C' && s.size() == 2) { // top 찾음
					...
				}
			}
			else if (idx[i] == 'C') {
				if (s.top() == 'P' && s.size() == 3) { // top 찾음
					...
				}
			}
		}

[조건을 추가한 코드 (정답)]

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

int main() {
	char idx[1001];
	cin.getline(idx, 1001, '\n');
	stack<char> s;
	for (int i = 0; i < 1001; i++) {
		if (idx[i] == 'U') {
			if (s.empty()) {
				//std::cout << "U";
				s.push(idx[i]);
			}
		}
		else if (!s.empty()) {
			if (idx[i] == 'C' && s.top() == 'U') {
				if (s.size() == 1) {
					// 마지막 C와 중복될 수 있어서
					//std::cout << "C";
					s.push(idx[i]);
				}
			}
			else if (idx[i] == 'P') {
				// 이 또한 마지막 C인데 P를 넣으면 안 되서
				// size도 조건에 추가한다.
				if (s.top() == 'C' && s.size() == 2) {
					//std::cout << "P";
					s.push(idx[i]);
				}
			}
			else if (idx[i] == 'C') {
				if (s.top() == 'P' && s.size() == 3) {
					//std::cout << "C";
					s.push(idx[i]);
				}
			}
		}
	}

	//std::cout << '\n' << s.size() << '\n';

	if (s.size() == 4) {
		std::cout << "I love UCPC";
	}
	else {
		std::cout << "I hate UCPC";
	}

	return 0;
}