본문 바로가기

Algorithm

[Programmers] 문자열 압축

https://programmers.co.kr/learn/courses/30/lessons/60057

 

코딩테스트 연습 - 문자열 압축

데이터 처리 전문가가 되고 싶은 "어피치"는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문

programmers.co.kr

🚀문제는 위에 들어가서 보시길~! 

 

문제 이해

처음에 문제를 잘못 이해해서 깨달음을 얻는 순간까지 굉장히 오래걸렸습니다. 그것도 2번이나!!!!! 😅

문자열을 N개 단위로 자르고 잘라진 문자열이 2개 이상 연속한다면 앞에 숫자 붙이는 방법으로 줄여서 얼마나 줄일 수 있냐는 문제입니다. 

 

문제에서 나온 예시를 한 개 가져오면,

"aabbaccc"는 1개 단위로 자른 문자열은 

["a", "a", "b",  "b", "a", "c", "c", "c"] 가 되고

2개 이상 연속하는 문자열을 문제의 방법대로 압축한다면

2a2ba3c 로 압축할 수 있습니다. (이게 최대로 압축한 것)

 

문자열의 길이 = X 라고 하자.

N개 단위로 자르는데 N의 범위는 1부터 X/2 까지 입니다. 왜냐면 절반이 최대로 압축한 것이고, 그 이상은 압축이 불가능합니다.

 

잘못 생각한 방법 1

저는 N의 조건은 무조건 문자열이 나누어 떨어져야한다고 생각했습니다.

즉, X=8 이라면, N = 1,2,4,8 이 된다고 생각한 거죠.... 

줄 그어 놓았으니 이렇게 생각하시면 안돼요... 

잘못 생각한 방법 2

또 N은 상황에 따라서 변할 수 있다고 생각했습니다. 

N=2로 딱 정해져 있는게 아니라 문자열에서 유동적으로 상황에 따라서 변할 수 있다고 생각해서... 정말 힘겹게 생각하고 있었는데ㅎ

띠용................

 

입출력 예에 대한 설명까지 꼭 봅시다.

 

문제 풀이

풀이도 생각보다 복잡했지만 그대로 구현만 하면 되는 문제였습니다.

먼저 N의 범위는 1 ... (문자열의길이/2) 이므로 반복문을 돌리며 문자열을 나누어주었습니다. 

그리고 나누어준 문자열을 하나씩 비교해주며 압축한 문자열을 만들어주었습니다. 

 

 

아래와 같이 풀긴 했지만 풀면서 실수가 많아 디버깅을 많이 했어야 했습니다.

5번 테케가 뭔지 몰라 질문을 봤으나 아주 친절한 분이 테케를 공유해주셔서 바로 알 수 있었습니다. 👉 https://programmers.co.kr/questions/20870

5번은 문자열이 "a"와 같이 한자리수일 때 나오는 오류였습니다. 

 

 

import Foundation

func sliceString(str: String, by: Int) -> [String] {
    var string = str
    var result = [String]()
    while string.count > 0 {
        if string.count < by {
            result.append(string)
            return result
        }
        let sliceIndex = string.index(string.startIndex, offsetBy: by)
        result.append(String(string[string.startIndex..<sliceIndex]))
        string = String(string[sliceIndex...])
    }
    return result
}

func solution(_ s:String) -> Int {
    let length: Int = s.count
    var minResult: Int = length
    
    if length < 2 { return 1 }
    for divide in 1...length/2 {
        let stringArray: [String] = sliceString(str: s, by: divide)
        var previousStr = stringArray.first!
        var count = 1
        var resultString = ""
        stringArray.enumerated().forEach {
            if stringArray.count == 1 {
                resultString += "\(previousStr)"
            } else {
                if $0.offset != 0 {
                    if $0.element == previousStr {
                        count += 1
                        if $0.offset == stringArray.count - 1 {
                            resultString += "\(count)\(previousStr)"
                        }
                    } else {
                        if count == 1 {
                            resultString += "\(previousStr)"
                        } else {
                            resultString += "\(count)\(previousStr)"
                        }
                        previousStr = $0.element
                        count = 1
                        if $0.offset == stringArray.count - 1 {
                            resultString += "\(previousStr)"
                        }
                    }
                }
            }
        }
        minResult = min(minResult, resultString.count)
    }
    return minResult
}

'Algorithm' 카테고리의 다른 글

[Programmers] 거리두기 확인하기  (0) 2022.02.04
[Programmers] 1차 추석 트래픽  (0) 2022.02.03
[Baekjoon] 1021 회전하는 큐  (0) 2022.01.12
[Swift] Union-Find 자료구조 구현해보기  (0) 2022.01.08
[Baekjoon] 10775 공항  (0) 2022.01.07