RosettaCodeData/Task/LZW-compression/Swift/lzw-compression.swift
2020-02-17 23:21:07 -08:00

63 lines
1.5 KiB
Swift

class LZW {
class func compress(_ uncompressed:String) -> [Int] {
var dict = [String : Int]()
for i in 0 ..< 256 {
let s = String(Unicode.Scalar(UInt8(i)))
dict[s] = i
}
var dictSize = 256
var w = ""
var result = [Int]()
for c in uncompressed {
let wc = w + String(c)
if dict[wc] != nil {
w = wc
} else {
result.append(dict[w]!)
dict[wc] = dictSize + 1
w = String(c)
}
}
if w != "" {
result.append(dict[w]!)
}
return result
}
class func decompress(_ compressed:[Int]) -> String? {
var dict = [Int : String]()
for i in 0 ..< 256 {
dict[i] = String(Unicode.Scalar(UInt8(i)))
}
var dictSize = 256
var w = String(Unicode.Scalar(UInt8(compressed[0])))
var result = w
for k in compressed[1 ..< compressed.count] {
let entry : String
if let x = dict[k] {
entry = x
} else if k == dictSize {
entry = w + String(w[w.startIndex])
} else {
return nil
}
result += entry
dict[dictSize+1] = w + String(entry[entry.startIndex])
w = entry
}
return result
}
}
let comp = LZW.compress("TOBEORNOTTOBEORTOBEORNOT")
print(comp)
if let decomp = LZW.decompress(comp) {
print(decomp)
}