ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Programmers) Lv2 [2020카카오공채] 괄호 변환
    Algorithm/Programmers 2020. 3. 25. 15:04

    출처: https://programmers.co.kr/learn/courses/30/lessons/60058

    분류: Lv2


    접근방식

    문제에서 알고리즘 방법을 단계별로 잘 나눠서 알려주고 있습니다.

    잘 읽고 "그대로" 구현만 잘 하면 되는 문제 입니다. 

    (그치만 그게 어렵네요 😭)

    포인트라면 반복적인 재귀형태가 들어가기 때문에 기능별로 함수를 쪼개서 구현하는 능력이 필요할 것 같네요.

     

    출제의도 역시 다음과 같습니다.

    주어진 로직을 그대로 구현할 수 있는지 파악

    재귀함수를 이해하고 작성할 수 있는지 파악

     

    해결방법

    저는 주요 기능 (함수)을 크게 4가지로 나눠봤습니다.

    1. 문자열을 쪼개는 1 ~ 4 번을 수행하는 함수 (trimming)

    func trimming(_ p: String) -> String {
        
        guard !isRight(p) else { return p }
        
        var v = p
        var u: String = String(v.removeFirst())
        var flagCount = 1
        
        while flagCount != 0 {
            let target = v.removeFirst()
            u += String(target)
            flagCount += target == p.first! ? 1 : -1
        }
        
        if isRight(u) {
            return u + trimming(v)
        } else {
            return "(\(trimming(v)))" + transformWrong(u)
        }
        
    }

    2. 올바른 문자열인지 확인하기 (isRight) 

    func isRight(_ str: String) -> Bool {
        var openCount = 0
        
        for c in str {
            if openCount < 0 { return false }
            openCount += c == "(" ? 1 : -1
        }
        
        return openCount == 0
    }

    3. u가 올바른 문자열이 아닐 때 변환하는 함수 (transformWrong)

    func transformWrong(_ str: String) -> String {
        var targetStr = str
        targetStr.removeFirst()
        targetStr.removeLast()
        
        return targetStr.reversedParenthesis
    }

    4. 괄호 뒤집기 (reversedParenthesis)

    extension String {
        var reversedParenthesis: String {
            var result = ""
            for c in self {
                result += (c == "(") ? ")" : "("
            }
            return result
        }
    }

    다음과 같이 개별적인 기능을 나눠서 함수를 구현했다면 나머지는 정말 문제의 설명을 잘 따라서 수행해주면 됩니다.

    단, 예제만 보고 "유추" 해서 푸는 것이 아니라 문제의 알고리즘을 읽고 그대로 구현해주셔야 실수를 방지할 수 있습니다.
    (네 저처럼 실수 하지 않으시려면요...)

     

    요약해서 대강 설명드리면...

     

    u가 올바른 문자열이라면 u + trmming(v)

    v를 조작해서 u 뒤에 v를 붙입니다.

     

    u가 올바른 문자열이라면 ( trimming(v) ) + tramsformWrong(u)

    v를 조작한 다음 뒤에 u를 붙입니다.

     

    총 풀이 입니다.

    import Foundation
    
    extension String {
        var reversedParenthesis: String {
            var result = ""
            for c in self {
                result += (c == "(") ? ")" : "("
            }
            return result
        }
    }
    
    func isRight(_ str: String) -> Bool {
        var openCount = 0
        
        for c in str {
            if openCount < 0 { return false }
            openCount += c == "(" ? 1 : -1
        }
        
        return openCount == 0
    }
    
    func trimming(_ p: String) -> String {
        
        guard !isRight(p) else { return p }
        
        var v = p
        var u: String = String(v.removeFirst())
        var flagCount = 1
        
        while flagCount != 0 {
            let target = v.removeFirst()
            u += String(target)
            flagCount += target == p.first! ? 1 : -1
        }
        
        if isRight(u) {
            return u + trimming(v)
        } else {
            return "(\(trimming(v)))" + transformWrong(u)
        }
        
    }
    
    func transformWrong(_ str: String) -> String {
        var targetStr = str
        targetStr.removeFirst()
        targetStr.removeLast()
        
        return targetStr.reversedParenthesis
    }
    
    func solution(_ p:String) -> String {
        
        guard !p.isEmpty else { return "" }
        
        return trimming(p)
    }

     

    배운점

    구현력은 기본 중의 기본.. 하라는 대로 하는 것도 못하면 안되겠죠?

     

    회고

    너무 느리다.

    빠르게 빠르게 

    연습 또 연습 😫😫😫

    댓글

Designed by Tistory.