ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Swift] 문자열 압축
    개발/Swift 2022. 3. 26. 22:12
    반응형

    문제를 해결하기 위해 두가지 기능을 함수로 구현해야한다.

    1. 주어진 스트링을 원하는 길이만큼 잘라 배열로 만든다
    2. 배열을 압축된 스트링으로 만든다.

    자를 길이는 1부터 주어진문자열의 반까지 가능하다.

    for sliceLength in 1...(s.count/2) {}
    

    예로 길이가 6,7인경우 1,2,3 개씩 자를수있다.

    8,9인경우는 1,2,3,4 개씩 자를수있다.

    만약 s의 길이가 3보다 적은경우는

    결국 s 의 길이와 같으므로 패스한다.

    ex>aa 의경우 2a ,aa 둘다 2의 길이

    if(s.count<3){ return s.count }
    

    결국 1부터 반복하여 압축된 스트링의 길이가 가장 짧은것이 해답이 된다

    func solution(_ s:String) -> Int {
        var answer = s.count
        if(s.count<3){ return s.count }
     
        for sliceLength in 1...s.count/2{
            var slicedArray = slice(length: sliceLength, string: s)
            var compressedString = compress(arr: slicedArray)
            answer = min(answer, compressedString.count)
        }
        return answer
    }
    

    이제 slice 와 compress 를 구현해본다.

    slice는 주어진문자열 을 배열로 변환한 후 원하는 길이만큼 빼서 리턴할 배열에 넣어주면된다.

    ex> 2개씩 자를경우 aa / bb / ac / cc

    하지만 만약 원하는 길이가 안나오는경우

    3개씩 자르는데 aab / bac / cc

    마지막 cc 는 그냥 넣어주는 로직이 필요하다

    func slice(length:Int, string:String) -> Array<String>{
        var temp = Array(string)
        var arr = [String]()
        while !temp.isEmpty {
            if(temp.count<length){
                var remainString = String(temp)
                arr.append(remainString)
                break
            }else{
                var slicedString = temp.prefix(length)
                arr.append(String(slicedString))
                temp.removeSubrange(0..<length)
            }
        }
    
        return arr
    }
    

    compress 함수는 우선 잘라진 배열만큼 반복문을 돌리면서 배열값을 비교할것이고

    같은지 다른지 에따라 다른 로직을 탈것이다

    여기서 만약 같으면 count 를 1씩 올리고

    나중에 이 count 값에 따라 result 에 더해질 문자열이 달라질것이다

    if(count > 1){
        result += "\\(count)\\(temp)"
    }else{
        result += temp
    }
    

    위와같이 1보다 큰경우 (이전에 같은 문자열이 나온경우)

    count와 문자열을 같이 넣어주었다.

    그리고 만약 마지막 반복에서 같은 문자열이 나오면

    count 만 증가시키고 result에 추가하지 않게되는데

    그런 경우를 대비해 로직을 또 넣어준다

    if(temp != ""){
            if(count > 1){
                result += "\\(count)\\(temp)"
            }else{
                result += temp
            }
            
        }
    

    compress 함수

    func compress(arr:Array<String>)-> String{
        var result = ""
        var temp = ""
        var count = 1
        for i in 0..<arr.count{
            if(i==0){ temp += arr[i]
            }else{
                if(arr[i] == temp){
                    count += 1
                }else{
                    if(count > 1){
                        result += "\\(count)\\(temp)"
                    }else{
                        result += temp
                    }
                    count = 1
                    temp = arr[i]
                    
                }
            }
            
        }
        if(temp != ""){
            if(count > 1){
                result += "\\(count)\\(temp)"
            }else{
                result += temp
            }
            
        }
        
        return result
    }
    
    반응형

    댓글

Designed by Tistory.