본문 바로가기

백준 PS일지/Stack

[백준/C언어] 9012번 :괄호 . 코드 리뷰+느낀점

스택의 개념을 모를 경우 아래 링크 참고하세요

2021.09.16 - [자료구조] - [C언어/자료구조] Stack. 스택의 의미와 필수 함수, 응용

문제

괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고 부른다. 한 쌍의 괄호 기호로 된 “( )” 문자열은 기본 VPS 이라고 부른다. 만일 x 가 VPS 라면 이것을 하나의 괄호에 넣은 새로운 문자열 “(x)”도 VPS 가 된다. 그리고 두 VPS x 와 y를 접합(concatenation)시킨 새로운 문자열 xy도 VPS 가 된다. 예를 들어 “(())()”와 “((()))” 는 VPS 이지만 “(()(”, “(())()))” , 그리고 “(()” 는 모두 VPS 가 아닌 문자열이다. 

여러분은 입력으로 주어진 괄호 문자열이 VPS 인지 아닌지를 판단해서 그 결과를 YES 와 NO 로 나타내어야 한다. 

입력

입력 데이터는 표준 입력을 사용한다. 입력은 T개의 테스트 데이터로 주어진다. 입력의 첫 번째 줄에는 입력 데이터의 수를 나타내는 정수 T가 주어진다. 각 테스트 데이터의 첫째 줄에는 괄호 문자열이 한 줄에 주어진다. 하나의 괄호 문자열의 길이는 2 이상 50 이하이다. 

출력

출력은 표준 출력을 사용한다. 만일 입력 괄호 문자열이 올바른 괄호 문자열(VPS)이면 “YES”, 아니면 “NO”를 한 줄에 하나씩 차례대로 출력해야 한다. 

 

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

 

9012번: 괄호

괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고

www.acmicpc.net

9012:괄호 풀면서 겪은 문제 + 느낀점

 

1.우선 stack을 정적변수로 할당했는데 초기화를 매번하는 것보다 그냥 지역변수로 선언하는 것이 났다고 생각했습니다.

 

2. 예제 1의 문장들은 정확하게 다 정답이었는데 알고보니 예제 2에 함정이 있었습니다.

 )) 또는 ())(() 이문제였습니다.

연속적으로 ))가 나올경우 pop연산을 연속 2번시행하는데 그럴경우 제 코드에선 top==-3이되는데

이를 받아줄 코드가 없어서 Runtime오류가 날 것입니다. 이를 보완하고자, 만약 입력받은 문자열 이 ')'일 경우에 top==-1( 스택이 비어있으면) 처음부터 )을 저장하는 것이므로 NO판정을 선언했습니다.

 

코드리뷰

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
typedef char PS; //Parenthesis String괄호문자열의 정의입니다.
int top = -1; //스택의 top입니다.
void pop() { //팝연산수행시 --top
	--top;
}
void push(PS stack[] , char ps) { // 스택을 맨처음에 정적변수로 선언했는데
	stack[++top] = ps; //초기화하기 애매해서 지역변수로 선언하기위해 매개변수로 stack을 받았습니다.
}
int main() {
	int n;
	scanf("%d", &n); //몇개의 문자를 검사할것인가?
	for (int i = 0; i < n; i++) {
		PS ps[50]; //입력받을 문자열
		PS stack[50]; //stack에 ( 저장.) 나올시 ( pop연산
		scanf("%s", &ps);
		for (int j = 0; j < sizeof(ps)/sizeof(PS); j++) {
			if (ps[j] == '(')
				push(stack, '(');
			else if (ps[j] == ')') { //만약 )일 때 
				if (top == -1) { //이미 이전에 아무것도 stack에 저장된 것이 없다면
					--top; // 8번째아래에 선언된 코드는 -1일때 yes기때문에 일부로 --시키고 break해서 no로 출력되게 했습니다.
					break;
				}
				pop();
			}
			else
				break;
		}
		if (top == -1) //만약 (와 )가 1ㄷ1 대응으로 만났다면 stack은 비어있을 것이고,
			printf("YES\n"); //그럴 경우 참!
		else
			printf("NO\n");
		top = -1;
	}
	return 0;
}