Algorithm/Baekjoon

[ Algorithm ] Baekjoon_9012 : Kotlin

Sheep1sik 2023. 11. 18. 01:58
반응형
출처: BAEKJOON 사이트

 

안녕하세요 공공돌🧸 입니다 !!

오늘은 백준 알고리즘의 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

반응형