개발/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
}