LZW compression: Difference between revisions

Content added Content deleted
m (Optimized Lua decompress using table.concat. On 1.2mb test data, ~44x faster. 58.8s to 1.3s)
Line 4,904: Line 4,904:
{{trans|JavaScript}}
{{trans|JavaScript}}
<lang swift>class LZW {
<lang swift>class LZW {
class func compress(uncompressed:String) -> [Int] {
class func compress(_ uncompressed:String) -> [Int] {
var dict = [String : Int]()
var dict = [String : Int]()

for i in 0 ..< 256 {
for i in 0 ..< 256 {
let s = String(UnicodeScalar(i))
let s = String(Unicode.Scalar(UInt8(i)))
dict[s] = 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 dictSize = 256
var w = ""
var dict = [Int : String]()

var result = [Int]()
for c in uncompressed {
for i in 0 ..< 256 {
let wc = w + String(c)
dict[i] = String(Unicode.Scalar(UInt8(i)))
if dict[wc] != nil {
}

w = wc
} else {
var dictSize = 256
result.append(dict[w]!)
var w = String(Unicode.Scalar(UInt8(compressed[0])))
dict[wc] = dictSize++
var result = w
for k in compressed[1 ..< compressed.count] {
w = String(c)
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
}
}
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(UnicodeScalar(i))
}
var dictSize = 256
var w = String(UnicodeScalar(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(first(w)!)
} else {
return nil
}
result += entry
dict[dictSize++] = w + String(first(entry)!)
w = entry
}
return result
}
}
}


let comp = LZW.compress("TOBEORNOTTOBEORTOBEORNOT")
let comp = LZW.compress("TOBEORNOTTOBEORTOBEORNOT")
println(comp)
print(comp)

if let decomp = LZW.decompress(comp) {
if let decomp = LZW.decompress(comp) {
println(decomp)
print(decomp)
}</lang>
}</lang>
{{out}}
{{out}}