![](https://blog.kakaocdn.net/dn/bZ9Z4W/btsAyNLdSEm/kGMQXApgrY3FYf4ofEp0JK/img.png)
안녕하세요 공공돌🧸 입니다 !!
오늘은 백준 알고리즘의 9012번: 괄호 문제를 풀어보고 리뷰를 해보려 합니다.
먼저 문제를 풀기 전 저의 목표는 알고리즘 문제 풀이도 있지만, 기능들을 나누어 구현하는것을 목표로 삼았습니다.
문제는 아래 링크를 참고해주세요.
9012번: 괄호
괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고
www.acmicpc.net
9012번 : 괄호
문제
괄호 문자열(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”를 한 줄에 하나씩 차례대로 출력해야 한다.
예제 입력 1
6
(())())
(((()())()
(()())((()))
((()()(()))(((())))()
()()()()(()()())()
(()((())()(
예제 출력 1
NO
NO
YES
NO
YES
NO
예제 입력 2
3
((
))
())(()
예제 출력 2
NO
NO
NO
기능 정리
✅ 시도 횟수 T를 입력받는다.
✅ 문자열을 입력 받는다.
✅ VPS를 검증한다.
- 문자가 "(" 이면 count ++
- 문자가 ")" 이면 count --
- count가 0보다 작은지 확인한다.
- count가 0이랑 같은지 확인한다.
핵심
이번 문제에서의 핵심은 아래와 같다고 생각합니다.
- 각 문자열을 순회하면서, 여는 괄호 '('를 만나면 카운트를 증가시키고, 닫는 괄호 ')'를 만나면 카운트를 감소시킵니다.
- 만약 어느 시점에서 카운트가 음수가 되면, 즉시 "NO"를 반환합니다. 이는 닫는 괄호가 여는 괄호보다 더 많이 나왔다는 의미이기 때문입니다.
- 모든 문자열을 순회한 후, 카운트가 정확히 0이면 "YES"를 반환합니다. 그렇지 않다면 "NO"를 반환합니다.
코드 구현
main
fun main() {
val input = readln().toInt()
for (total in 1..input) {
println(if (isValidParenthesis(readln())) "YES" else "NO")
}
}
반환받은 값이 true 면 Yes 를 출력하고 false 이면 NO를 출력합니다.
isValidParenthesis
fun isValidParenthesis(input: String): Boolean {
var count = 0
for (char in input){
count = incrementCountForOpenParenthesis(count,char)
count = decrementCountForCloseParenthesis(count,char)
if (returnFalseIfCountNegative(count)){
return false
}
}
return isCountZero(count)
}
입력받은 문자열을 순회시킵니다.
문자가 해당 조건에 맞으면 반환되는 count값을 count 변수에 넣습니다.
반환받은 조건값이 true면 false를 반환합니다.
순회가 끝난 후 count가 0과 같다면 true 같지 않다면 false를 반환합니다.
incrementCountForOpenParenthesis
private fun incrementCountForOpenParenthesis(count: Int, char: Char): Int {
var copyCount = count
if (char == '(' ){ copyCount++ }
return copyCount
}
문자가 '(' 이면 카운트를 증가시킵니다.
decrementCountForCloseParenthesis
private fun decrementCountForCloseParenthesis(count: Int, char: Char): Int {
var copyCount = count
if (char == ')' ){ copyCount-- }
return copyCount
}
문자가 ')' 이면 카운트를 감소시킵니다.
returnFalseIfCountNegative
private fun returnFalseIfCountNegative(count: Int): Boolean {
return count < 0
}
count가 0보다 작은지 검증합니다.
isCountZero
private fun isCountZero(count: Int): Boolean {
return count == 0
}
count가 0과 같은지 검증합니다.
최종 코드 구현
fun main() {
val input = readln().toInt()
for (total in 1..input) {
println(if (isValidParenthesis(readln())) "YES" else "NO")
}
}
fun isValidParenthesis(input: String): Boolean {
var count = 0
for (char in input){
count = incrementCountForOpenParenthesis(count,char)
count = decrementCountForCloseParenthesis(count,char)
if (returnFalseIfCountNegative(count)){
return false
}
}
return isCountZero(count)
}
private fun incrementCountForOpenParenthesis(count: Int, char: Char): Int {
var copyCount = count
if (char == '(' ){ copyCount++ }
return copyCount
}
private fun decrementCountForCloseParenthesis(count: Int, char: Char): Int {
var copyCount = count
if (char == ')' ){ copyCount-- }
return copyCount
}
private fun returnFalseIfCountNegative(count: Int): Boolean {
return count < 0
}
private fun isCountZero(count: Int): Boolean {
return count == 0
}
결과
공부하는 공돌이, 공공돌입니다🐻
@sheep1sik
'Algorithm > Baekjoon' 카테고리의 다른 글
[ Algorithm ] Baekjoon_10813 : Kotlin (6) | 2023.11.24 |
---|---|
[ Algorithm ] Baekjoon_2609 : Kotlin (1) | 2023.11.22 |