본문 바로가기
알고리즘 문제풀이

[프로그래머스] 압축 (Swift)

by SiO2whocode 2025. 2. 21.
728x90

https://school.programmers.co.kr/learn/courses/30/lessons/17684?language=swift

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

구현 (투포인터..?)

대문자 영어로 구성된 문자열이 주어지면, 그 문자열을 LZW(Lempel–Ziv–Welch) 압축 방법을 사용해서 압축하는 건데

LZW 방법이 참..우선 A~Z까지 1~26 번호로 매핑된 맵이 있다고 한다. 문자열을 왼쪽에서부터 보면서 맵에 해당 문자열이 있으면 우선 맵에 없는 문자열 구간이 나올 때 까지 오른쪽으로 간 다음, 맵에 없는 문자열을 맵의 제일 끝에 추가한다 인덱스 번호는 맵에서 최대 인덱스+1 이 된다. 그리고 맵에 있는 최장길이 문자열 (즉 마지막 문자 뺀 문자열)에 해당하는 인덱스를 출력한다.

 

접근방법

복잡한 방법일 뿐 방법이 다 문제에 나와있기 때문에 그대로 구현만 하면 되는데,,

우선 맵을 만들어야함 A~Z까지 1~26을 대응시킨 맵. Swift는 String과 character와 int간 자유로운 형변환이 안되기 때문에..UnicodeScalar 메서드를 썼는데,, 더 간단한 방법이 있다면 알고싶음..

var map:[String:Int] = [:]
for i in 1...26 {
    map[String(UnicodeScalar(64+i)!)] = i
}

그러면 map = ["A":1, "B":2 ,,, "Z":26] 이 된다. 현재 맵의 최대 인덱스는 26이고 추가된다면 그 문자열의 인덱스는 27이 될 것.

 

그 다음은 반복문을 순회하면서 사용할 변수들을 정의해주는 것인데,

- msg길이 = n

- s는 현재 보고 있는 문자열의 시작점

- e는 끝점

- cur은 현재 보고 있는 문자열

- maxIndex는 현재 맵의 최대 인덱스

입니다.

var n = msgArr.count
var s = 0
var e = 0
var cur = ""
var maxIndex = 26

 

그럼 이제 반복문 시작

종료조건은 e가 n이 됐을 때 (메세지 범위 넘어감) n-1까지의 문자열의 인덱스를 출력해주는 것

(e-1 = n-1 까지의 문자열은 있었거나, 없었어도 그 전 단계에서 맵에 넣어줬을 것이기 때문에 강제추출)

 

반복문은 기본적으로 s~e까지 범위의 문자열이 맵에 있는지 없는지 확인하는 과정이다.

맵에 있다면 없을 때까지 e를 오른쪽으로 이동시키고,

없다면 바로 전 문자까지만 포함한 문자열의 인덱스를 출력하고

지금 없는 문자열은 맵에 새로 추가한다.

while e <= n {
    if e == n {
        result.append(map[msgArr[s..<e].joined()]!)
        break
    }
    cur = msgArr[s...e].joined()
    if map[cur] != nil {
        e += 1
        continue
    } else {
        maxIndex += 1
        map[cur] = maxIndex
        result.append(map[msgArr[s..<e].joined()]!)
        s = e
    }
}

 

소스코드

func solution(_ msg:String) -> [Int] {
    var result:[Int] = []
    
    var msgArr:[String] = Array(msg).map{String($0)}
    var map:[String:Int] = [:]
    for i in 1...26 {
        map[String(UnicodeScalar(64+i)!)] = i
    }
    
    var n = msgArr.count
    var s = 0
    var e = 0
    var cur = ""
    var maxIndex = 26
    
    while e <= n {
        if e == n {
            result.append(map[msgArr[s..<e].joined()]!)
            break
        }
        cur = msgArr[s...e].joined()
        if map[cur] != nil {
            e += 1
            continue
        } else {
            maxIndex += 1
            map[cur] = maxIndex
            result.append(map[msgArr[s..<e].joined()]!)
            s = e
        }
    }
    
    return result
}
728x90