Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,97 @@
package main
import (
"container/heap"
"fmt"
)
type HuffmanTree interface {
Freq() int
}
type HuffmanLeaf struct {
freq int
value rune
}
type HuffmanNode struct {
freq int
left, right HuffmanTree
}
func (self HuffmanLeaf) Freq() int {
return self.freq
}
func (self HuffmanNode) Freq() int {
return self.freq
}
type treeHeap []HuffmanTree
func (th treeHeap) Len() int { return len(th) }
func (th treeHeap) Less(i, j int) bool {
return th[i].Freq() < th[j].Freq()
}
func (th *treeHeap) Push(ele interface{}) {
*th = append(*th, ele.(HuffmanTree))
}
func (th *treeHeap) Pop() (popped interface{}) {
popped = (*th)[len(*th)-1]
*th = (*th)[:len(*th)-1]
return
}
func (th treeHeap) Swap(i, j int) { th[i], th[j] = th[j], th[i] }
func buildTree(symFreqs map[rune]int) HuffmanTree {
var trees treeHeap
for c, f := range symFreqs {
trees = append(trees, HuffmanLeaf{f, c})
}
heap.Init(&trees)
for trees.Len() > 1 {
// two trees with least frequency
a := heap.Pop(&trees).(HuffmanTree)
b := heap.Pop(&trees).(HuffmanTree)
// put into new node and re-insert into queue
heap.Push(&trees, HuffmanNode{a.Freq() + b.Freq(), a, b})
}
return heap.Pop(&trees).(HuffmanTree)
}
func printCodes(tree HuffmanTree, prefix []byte) {
switch i := tree.(type) {
case HuffmanLeaf:
// print out symbol, frequency, and code for this
// leaf (which is just the prefix)
fmt.Printf("%c\t%d\t%s\n", i.value, i.freq, string(prefix))
case HuffmanNode:
// traverse left
prefix = append(prefix, '0')
printCodes(i.left, prefix)
prefix = prefix[:len(prefix)-1]
// traverse right
prefix = append(prefix, '1')
printCodes(i.right, prefix)
prefix = prefix[:len(prefix)-1]
}
}
func main() {
test := "this is an example for huffman encoding"
symFreqs := make(map[rune]int)
// read each symbol and record the frequencies
for _, c := range test {
symFreqs[c]++
}
// build tree
tree := buildTree(symFreqs)
// print out results
fmt.Println("SYMBOL\tWEIGHT\tHUFFMAN CODE")
printCodes(tree, []byte{})
}

View file

@ -0,0 +1,65 @@
package main
import (
"container/heap"
"fmt"
)
type coded struct {
sym rune
code string
}
type counted struct {
total int
syms []coded
}
type cHeap []counted
// satisfy heap.Interface
func (c cHeap) Len() int { return len(c) }
func (c cHeap) Less(i, j int) bool { return c[i].total < c[j].total }
func (c cHeap) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
func (c *cHeap) Push(ele interface{}) {
*c = append(*c, ele.(counted))
}
func (c *cHeap) Pop() (popped interface{}) {
popped = (*c)[len(*c)-1]
*c = (*c)[:len(*c)-1]
return
}
func encode(sym2freq map[rune]int) []coded {
var ch cHeap
for sym, freq := range sym2freq {
ch = append(ch, counted{freq, []coded{{sym: sym}}})
}
heap.Init(&ch)
for len(ch) > 1 {
a := heap.Pop(&ch).(counted)
b := heap.Pop(&ch).(counted)
for i, c := range a.syms {
a.syms[i].code = "0" + c.code
}
for i, c := range b.syms {
b.syms[i].code = "1" + c.code
}
heap.Push(&ch, counted{a.total + b.total, append(a.syms, b.syms...)})
}
return heap.Pop(&ch).(counted).syms
}
const txt = "this is an example for huffman encoding"
func main() {
sym2freq := make(map[rune]int)
for _, c := range txt {
sym2freq[c]++
}
table := encode(sym2freq)
fmt.Println("Symbol Weight Huffman Code")
for _, c := range table {
fmt.Printf(" %c %d %s\n", c.sym, sym2freq[c.sym], c.code)
}
}