본문 바로가기

ALGORITHM/문자열

[Swift] Lv2.문자열 압축 (String.Index)

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

 

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

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

programmers.co.kr

 

생각

처음에 문제를 봤을 땐 친절하게 주어진 5번째 예시 테케를 못보고

중간에도 마음대로 자를 수 있는줄 알고 이게 Lv2..? 하고 절망했는데.. 문제를 잘못 생각했었습니다..

처음부터 length 씩 자르는게 정해져있었습니다.

 

aabab 를 2개씩 자른다고 하면

[a] [ab] [ab]

이렇게 자를 수는 없고, 무조건

[aa] [ba] [b]

이렇게 잘라서 압축을 해야했습니다.

 

로직

slicing 함수로 문자열을 자르고

compressedLength 함수로 자른 문자열의 길이로 압축하여 그 길이를 반환하였습니다.

 

 

코드

그리고 String.Index

Swift 에서 subString 을 구하는건 정말 어려웠습니다 호호..

여기서 사용한 방법은 String.Index 타입의 startIndex, endIndex 시작과 끝의 인덱스를 구하고 (Int 형이 아닙니다.)

인덱스를 사용해 subString 으로 반환한 값을 String 으로 형변환하여 사용하였습니다.

 

미래의 저는 이걸 이해를 못할 수도 있기 때문에 코드를 덛붙이자면

let str: String = "abc"

let strStartIndex: String.Index = str.startIndex
let strEndIndex: String.Index = str.endIndex

let strSubString: SubString = str[strStartIndex..<strEndIndex]

let strString: String = String(strSubString)

String.Index 타입의 시작 인덱스, 끝 인덱스를 구하고

SubString 타입의 변수를 구한 후에

String 타입으로 변환합니다.

 

중간 인덱스를 구하고 싶다면

let s: String = "abc"

let index: Stiring.Index = s.index(s.startIndex, offsetBy: 1)

 

 

전체코드

import Foundation

func slicing(_ s: String, _ length: Int) -> [String] {
    var slicingString: [String] = []
    
    for i in stride(from: 0, to: s.count, by: length) {
        let startIndex = s.index(s.startIndex, offsetBy: i)
        var endIndex = s.index(s.startIndex, offsetBy: i)
        if s.count < i + length {
            endIndex = s.endIndex 
            slicingString.append(String(s[startIndex..<endIndex]))
            break
        }
        else {
            endIndex = s.index(s.startIndex, offsetBy: i + length)
        }
        slicingString.append(String(s[startIndex..<endIndex]))
    }
    
    return slicingString
}

func compressedLength(_ s: [String]) -> Int {
    var count: Int = 0
    var startString: String = ""
    var compressedString: String = ""
    for str in s {
        if startString == str {
            count = count + 1
        }
        else {
            if startString != "" {
                compressedString.append(count == 1 ? "\(startString)" : "\(count)" + "\(startString)")
            }
            startString = str
            count = 1
        }
    }
    compressedString.append(count == 1 ? "\(startString)" : "\(count)" + "\(startString)")
    return compressedString.count
}

func solution(_ s: String) -> Int {
    var minLength: Int = s.count
    
    if minLength <= 2 {
        return minLength
    }
    
    for slice in 1...s.count/2 {
        let slicedStringArray = slicing(s, slice)
        let length = compressedLength(slicedStringArray)
        if length < minLength {
            minLength = length
        } 
    }
    
    return minLength
}

 

 

 

 

 

 

https://developer.apple.com/documentation/swift/string

 

Apple Developer Documentation

 

developer.apple.com