[C언어] 백준 2504 괄호의 값
본문 바로가기

백준 C언어

[C언어] 백준 2504 괄호의 값

728x90
반응형

문제

4개의 기호 ‘(’, ‘)’, ‘[’, ‘]’를 이용해서 만들어지는 괄호열 중에서 올바른 괄호열이란 다음과 같이 정의된다.

  1. 한 쌍의 괄호로만 이루어진 ‘()’와 ‘[]’는 올바른 괄호열이다.
  2. 만일 X가 올바른 괄호열이면 ‘(X)’이나 ‘[X]’도 모두 올바른 괄호열이 된다.
  3. X와 Y 모두 올바른 괄호열이라면 이들을 결합한 XY도 올바른 괄호열이 된다.

예를 들어 ‘(()[[]])’나 ‘(())[][]’ 는 올바른 괄호열이지만 ‘([)]’ 나 ‘(()()[]’ 은 모두 올바른 괄호열이 아니다. 우리는 어떤 올바른 괄호열 X에 대하여 그 괄호열의 값(괄호값)을 아래와 같이 정의하고 값(X)로 표시한다.

  1. ‘()’ 인 괄호열의 값은 2이다.
  2. ‘[]’ 인 괄호열의 값은 3이다.
  3. ‘(X)’ 의 괄호값은 2×값(X) 으로 계산된다.
  4. ‘[X]’ 의 괄호값은 3×값(X) 으로 계산된다.
  5. 올바른 괄호열 X와 Y가 결합된 XY의 괄호값은 값(XY)= 값(X)+값(Y) 로 계산된다.

예를 들어 ‘(()[[]])([])’ 의 괄호값을 구해보자. ‘()[[]]’ 의 괄호값이 2 + 3×3=11 이므로 ‘(()[[]])’의 괄호값은 2×11=22 이다. 그리고 ‘([])’의 값은 2×3=6 이므로 전체 괄호열의 값은 22 + 6 = 28 이다.

여러분이 풀어야 할 문제는 주어진 괄호열을 읽고 그 괄호값을 앞에서 정의한대로 계산하여 출력하는 것이다.

입력

첫째 줄에 괄호열을 나타내는 문자열(스트링)이 주어진다. 단 그 길이는 1 이상, 30 이하이다.

출력

첫째 줄에 그 괄호열의 값을 나타내는 정수를 출력한다. 만일 입력이 올바르지 못한 괄호열이면 반드시 0을 출력해야 한다.

예제 입력 1 

(()[[]])([])

예제 출력 1 

28

예제 입력 2 

[][]((])

예제 출력 2 

0

 

괄호 문자열을 받고 괄호를 수식 형태로 구현시키는 문제입니다.

전형적인 구현 문제인데요

 

이 문제를 푸는 방법은 스택 자료구조를 사용해서 풀 수도 있겠지만 저는 단순 for문으로 풀었습니다.

괄호는 대괄호, 소괄호 두개로만 분류되기 때문에 if문 조금만 사용하면 되서 스택으로 풀지는 않았습니다.

 

( *= 2
[ *= 3
) /= 2
] /= 3

소괄호는 2배 대괄호는 3배씩 늘어나는 구조라서

여는 소괄호 ( "(" )인 경우 *= 2

닫는 소괄호 ( ")" )인 경우 /= 2

여는 대괄호 ( "[" )인 경우 *= 3

닫는 대괄호 ( "]" )인 경우 /= 3

이런식으로 각각 if문을 줘서 상황에 맞게 값을 변동시켜주면 됩니다.

 

반응형

전체 코드

#include <stdio.h>

char	str[31];
int cart = 1, row_left = 0, row_right = 0, high_left = 0, high_right = 0, result = 0, f = 0;
int main(void)
{
	scanf("%s", str);
	for(int i = 0; str[i]; i++)
	{
		if (str[i] == '(')
		{
			f = 1;
			row_left++;
			cart *= 2;
		}
		else if (str[i] == '[')
		{
			f = 2;
			high_left++;
			cart *= 3;
		}
		else if (str[i] == ')')
		{
			row_right++;
			if (row_right > row_left)            // "[)(]" 예외 처리
				break ;
			if (f == 1)
				result += cart;
			if (f == 2)                          // 이전 괄호가 대괄호인 경우 예외 처리
			{
				result = 0;
				break ;
			}
			cart /= 2;
			f = 0;
		}
		else if (str[i] == ']')
		{
			high_right++;
			if (high_right > high_left)            // "(][)" 예외 처리
				break ;
			if (f == 2)
				result += cart;
			if (f == 1)                            // 이전 괄호가 소괄호인 경우 예외 처리
			{
				result = 0;
				break ;
			}
			cart /= 3;
			f = 0;
		}
		else
			break ;
	}
    // 괄호 대칭이 서로 맞지 않는다면 예외 처리
	if (row_left != row_right || high_left != high_right)
		result = 0;
	printf("%d\n", result);
	return (0);
}

맨 처음 str 배열로 괄호 문자열을 입력받고

문자열 길이 만큼 for문으로 반복해줍니다.

 

반복할 때마다

if문으로 각각 상황에 맞게 값을 바꿔주고

괄호 이외의 값이 들어온 경우 예외 처리를 해줍니다.

 

그리고 괄호가 다중으로 있는경우 닫힐 때마다 값을 더하면 안되기에 플래그 변수를 세워서 값을 더해줍니다.

그리고 "( [ ) ]" 와 같은 경우 예외 처리를 해야하니까 이전 괄호가 ( 인 경우 플래그 변수를 1로

이전 괄호가 [ 인 경우 플래그 변수를 2로 설정해서 상황에 맞게 값을 더해주고 잘못된 경우 예외 처리를 해주었습니다.

 

이렇게 상황에 맞게 반복문을 다 돌린 후

괄호가 서로 대칭이 되지 않았다면

예외 처리를 해줍니다.

 

예외처리의 경우

"( [ ) ]"

"( ( ] )"

"A( [ ] )"

"( ] [ )"

위 네가지를 신경 써서 했습니다.

 

 

 

다른 분들의 코드를 보니까 다들 스택 자료구조를 구현하셔서 푸셔가지고 

제가 푼 코드를 보니 뭔가 야매(?) 느낌이 나서 죄책감이 드네요;; ㅋㅋㅋ

728x90
반응형

'백준 C언어' 카테고리의 다른 글

[C언어] 백준 5430 AC  (2) 2023.01.25
[C언어] 백준 7576 토마토  (0) 2023.01.20
[C언어] 백준 2667 단지번호붙이기  (0) 2023.01.14
[C언어] 백준 1049 기타줄  (0) 2023.01.12
[C언어] 백준 1541 잃어버린 괄호  (0) 2023.01.10