PS/프로그래머스

[프로그래머스] 문자열 압축

Hamp 2024. 9. 16. 23:25
반응형

문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

입력

s = "길이가 1 이상 1,000 이하인 문자열 "

 

출력

압축된 문자열의 가장 짧은 길이

해석

1. 문자열의 압축 한계는 문자열 길이의 절반까지다. ex) aabb/aabb -> 2aabb

2. 현재 문자열과 다음 문자열이 같으면 압축횟수를 증가시키기고 , 그렇지 않으면 지금까지 압축한 문자열을 더해준다.

3. 단, 문자열 압축횟수가 1이면 생략이 가능하다.

4. 남은 잔여 문자열이 있다면 그냥 더해준다.

코드

import Foundation

extension String {
    subscript(_ index: Int) -> String {
        return String(self[self.index(self.startIndex, offsetBy: index)])
    }
    
    subscript(_ range: Range<Int>) -> String {
        let fromIndex = self.index(self.startIndex, offsetBy: range.startIndex)
        let toIndex = self.index(self.startIndex, offsetBy: range.endIndex)
        return String(self[fromIndex..<toIndex])
    }
    
}

func solution(_ s:String) -> Int {
    
    var minLength = s.count 
    
    for compress in stride(from: 1, through: s.count/2, by:1) { // 압축 길이는 1 ~ 문자열 길이의 절반까지 

        var count: Int = 1 // 압축 횟수 
        var arr: [String] = []
        var now: String = s[0..<compress] // 현재 기준 문자열 
        var lastCompressedIndex: Int = 0 // 마지막 압축된 문자열 
        
        // 압축 길이만큼 자르면서 진행 
        for i in stride(from:compress, through: s.count - compress ,by:compress) {
            
            let next = s[i..<i+compress] // 다음 문자열  
            
            if now == next  { // 현재 문자열과 다음 문자열과 같으면 압축 , count + 1
                count += 1 
            } else { // 같지 않으면 현재 문자는 압축 불가
                // 압축 횟수가 1이면 생략가능
                let compressedText =  count != 1 ? "\(count)\(now)" : now
                arr.append(compressedText)
                now = next // 현재 문자열 다음 문자열로 갱신
                count = 1  // 압축 횟수도 1로 초기화
            }
            
            lastCompressedIndex = i + compress // 마지막 압축된 인덱스를 계속 추적
        } 
        
        // 반복문을 빠져 나온 후 now를 처리 
        let compressedText =  count != 1 ? "\(count)\(now)" : now
        arr.append(compressedText)
        
        // 마지막 압축 인덱스가 전체 문자 길이보다 작다면 
        if lastCompressedIndex < s.count {
            // 남은 잔여 문자 처리
            arr.append(s[lastCompressedIndex..<s.count])
        }
        // 현재 compress를 기준으로 압축된 최종 문자열과 길이 비교 후 갱신
        minLength = min(minLength, arr.joined().count)    
    }
    return minLength
}
반응형