기본 콘텐츠로 건너뛰기

백준알고리즘 9012번, 괄호 풀이

이번문제는 괄호의 유효성을 판단하는 문제이다.
소괄호만을 사용했기 때문에 푸는 방법은 쉬운문제 였으나 스택 수열 문제에서 사용한 스택 클래스를 그대로 사용함으로써
런타임에러가 발생하여 수정하느라 얘를 먹었다.
스택이 Pop() 메소드에서 size가 0인 경우에도 동작하게 만들어 배열의 범위를 벗어나는 접근이 가능하기 때문에 런타임에러가 난것으로 보인다.
size가 0인 경우 0을 리턴하도록 수정하니 잘 작동했다.(런타임 에러 메시지를 볼 수 있으면 좋으련만....)

접근방법 :
여는 괄호'(' 인 경우 push를 한다. 닫은 괄호')'이면서 스택이 비어있지 않다면 pop을 한다.
(제대로된 괄호라면 닫는 괄호가 나온경우 스택이 비어있을 수 없다.)
모든 괄호를 처리한 후에 스택이 비어있는지 확인한다. 괄호의 짝이 맞다면 무조건 비어있게 된다.

#include <stdio.h>
#include <string.h>

using namespace std;

#define MAX_STACK_SIZE 1000

class Stack {
private:
unsigned int size;
int stack[MAX_STACK_SIZE];
public:
Stack() {
size = 0;
memset(stack, 0, sizeof stack);
}
int Size() {
return size;
}
bool Empty(){
return size == 0;
}
int Top(){
if (size == 0)
return 0;
return stack[size-1];
}
void Push(int item)
{
stack[size++] = item;
}
int Pop() {
        if (size == 0)
return 0;
int temp = stack[size - 1];
stack[--size] = 0;
return temp;
}
};

int main(void) {
Stack st1;
int n = 0;
char sign[51] = { 0 };
bool breakflag = false;
char c = 0;
int cnt = 0;

scanf("%d", &n);
for (int i = 0; i < n; i++)
{
        memset(sign, 0, sizeof sign);
scanf("%s", sign);
cnt = 0;
while ((c = sign[cnt]) != '\0')
{
sign[cnt++] = 0;
if (c == '(')
{
st1.Push(c);
}
else
{
if (st1.Pop() == 0)
{
printf("NO\n");
breakflag = true;
break;
}

}
}

if (breakflag)
{
breakflag = false;
continue;
}

st1.Empty() == true ? printf("YES\n") : printf("NO\n");
while (st1.Empty() != true)
{
st1.Pop();
}

}

return 0;
}

댓글

이 블로그의 인기 게시물

2017 암호경진대회 4번

가장 쉽게 풀었죠. 30분도 안걸렸던거 같네요. 프로그램을 통해서 암호문의 유효성이 검증되는데요, 역공학을 통해서 암호문을 쉽게 찾을 수 있습니다. 답안  : Snow White and the Seven Dwarfs!. 풀이  : Oracle 함수가  CRC 를 계산하기 위해서는 중간에 평문이 복구될 것으로 보였다 .  제공하는  dll 을 이용하여  Oracle 함수의 입력으로 암호문을 넣은 프로그램을 작성하였다 . IDA 와  Immunity Debugger 를 이용해 프로그램을 역공학하여 얻을 수 있었다 .