This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,60 @@
record huffnode(l,r,n,c) # internal and leaf nodes
record huffcode(c,n,b,i) # encoding table char, freq, bitstring, bits (int)
procedure main()
s := "this is an example for huffman encoding"
Count := huffcount(s) # frequency count
Tree := huffTree(Count) # heap and tree
Code := [] # extract encodings
CodeT := table()
every x := huffBits(Tree) do
put( Code, CodeT[c] := huffcode( c := x[-1], Count[c].n, b := x[1:-1], integer("2r"||b) ) )
Code := sortf( Code, 1 ) # show table in char order
write("Input String : ",image(s))
write(right("char",5), right("freq",5), " encoding" )
every write(right(image((x := !Code).c),5), right(x.n,5), " ", x.b )
end
procedure huffBits(N) # generates huffman bitcodes with trailing character
if \N.c then return N.c # . append leaf char code
suspend "0" || huffBits(N.l) # . left
suspend "1" || huffBits(N.r) # . right
end
procedure huffTree(T) # two queue huffman tree method
local Q1,Q2,x,n1,n2
Q1 := [] # queue of characters and weights
every x := !T do # ensure all are huffnodes
if type(x) == "huffnode" then put(Q1,x) else runerr(205,x)
Q1 := sortf(Q1,3) # sort by weight ( 3 means by .n )
if *Q1 > 1 then Q2 := []
while *Q1+*\Q2 > 1 do { # While there is more than one node ...
n1 := if Q1[1] & ( ( Q1[1].n <= Q2[1].n ) | not Q2[1] ) then get(Q1) else get(Q2) # lowest weight from Q1 or Q2
n2 := if Q1[1] & ( ( Q1[1].n <= Q2[1].n ) | not Q2[1] ) then get(Q1) else get(Q2) # lowest weight from Q1 or Q2
put( Q2, huffnode( n1, n2, n1.n + n2.n ) ) # new weighted node to end of Q2
}
return (\Q2 | Q1)[1] # return the root node
end
procedure huffcount(s) # return characters and frequencies in a table of huffnodes by char
local c,T
T := table()
every c := !s do {
/T[c] := huffnode(,,0,c)
T[c].n +:= 1
}
return T
end

View file

@ -0,0 +1,30 @@
import Collections
procedure main(A)
every line := !&input do {
every (t := table(0))[!line] +:= 1 # Frequency table
heap := Heap(sort(t), field, "<") # Initial priority queue
while heap.size() > 1 do { # Tree construction
every (p1|p2) := heap.get()
heap.add([&null, p1[2]+p2[2], p1, p2])
}
codes := treeWalk(heap.get(),"") # Get codes from tree
write("Huffman encoding:") # Display codes
every pair := !sort(codes) do
write("\t'",\pair[1],"'-> ",pair[2])
}
end
procedure field(node) # selector function for Heap
return node[2] # field to use for priority ordering
end
procedure treeWalk(node, prefix, codeMap)
/codeMap := table("")
if /node[1] then { # interior node
treeWalk(node[3], prefix||"0", codeMap)
treeWalk(node[4], prefix||"1", codeMap)
}
else codeMap[node[1]] := prefix
return codeMap
end