Skip to content

Instantly share code, notes, and snippets.

@thanhpp
Last active October 18, 2021 07:52
Show Gist options
  • Save thanhpp/2245980b6d7f04e2cd131dbc062d6edb to your computer and use it in GitHub Desktop.
Save thanhpp/2245980b6d7f04e2cd131dbc062d6edb to your computer and use it in GitHub Desktop.
Compress_LempelZivWelch
package main
import (
"fmt"
"strings"
)
var (
input = "booop"
)
func main() {
res, dic := LZWComp([]byte(input))
fmt.Println("result = ", res)
var revertDic = make(map[string]string)
for k, v := range dic {
revertDic[v] = k
}
compressed := strings.Split(res, " ")
deComp := LZWDecomp(compressed, revertDic)
fmt.Println("decomp =", deComp)
fmt.Println("input == deComp:", input == deComp)
}
func LZWComp(in []byte) (string, map[string]string) {
fmt.Println("-----compress-----")
var (
w []byte
dic = make(map[string]string)
counter int = 100
res string
)
w = append(w, in[0])
for i := 1; i < len(in); i++ {
tmp := append(w, in[i])
_, ok := dic[string(tmp)]
if ok {
w = append(w, in[i])
continue
}
dic[string(tmp)] = fmt.Sprintf("%d", counter)
counter++
if len(w) == 1 {
res += string(w) + " "
} else {
res += dic[string(w)] + " "
}
w = []byte{in[i]}
}
res += string(w)
fmt.Println("dictionary")
for k, v := range dic {
fmt.Printf("%-5s = %s\n", k, v)
}
return res, dic
}
func LZWDecomp(in []string, dic map[string]string) string {
fmt.Println("-----decompress-----")
var (
w string
res string
)
res += in[0]
w += in[0]
fmt.Printf("in: %s\nw: %s\nout: %s\n----\n", in[0], w, res)
for i := 1; i < len(in); i++ {
v, ok := dic[in[i]]
if ok {
entry := v
res += entry
dic[w+string(entry[0])] = w + string(entry[0])
w = entry
fmt.Printf("in: %s\nw: %s\nout: %s\n----\n", in[i], w, res)
continue
}
if len(in[i]) == 1 {
entry := in[i]
res += entry
dic[w+string(entry[0])] = w + string(entry[0])
w = entry
fmt.Printf("in: %s\nw: %s\nout: %s\n----\n", in[i], w, res)
continue
}
entry := w + string(w[0])
res += entry
dic[entry] = entry
w = entry
fmt.Printf("in: %s\nw: %s\nout: %s\n----\n", in[i], w, res)
}
fmt.Println("dictionary")
for k, v := range dic {
fmt.Printf("%-5s = %s\n", k, v)
}
return res
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment