2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -17,6 +17,12 @@ A Huffman encoding can be computed by first creating a tree of nodes:
|
|||
## Add the new node to the queue.
|
||||
# The remaining node is the root node and the tree is complete.
|
||||
|
||||
<br>
|
||||
Traverse the constructed binary tree from root to leaves assigning and accumulating a '0' for one branch and a '1' for the other at each node. The accumulated zeros and ones at each leaf constitute a Huffman encoding for those symbols and weights:
|
||||
|
||||
'''Using the characters and their frequency from the string ''"this is an example for huffman encoding"'', create a program to generate a Huffman encoding for each character as a table.'''
|
||||
|
||||
;Task:
|
||||
Using the characters and their frequency from the string:
|
||||
::::: ''' '' this is an example for huffman encoding '' '''
|
||||
create a program to generate a Huffman encoding for each character as a table.
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -106,7 +106,8 @@ void decode(const char *s, node t)
|
|||
int main(void)
|
||||
{
|
||||
int i;
|
||||
const char *str = "this is an example for huffman encoding", buf[1024];
|
||||
const char *str = "this is an example for huffman encoding";
|
||||
char buf[1024];
|
||||
|
||||
init(str);
|
||||
for (i = 0; i < 128; i++)
|
||||
|
|
|
|||
52
Task/Huffman-coding/Kotlin/huffman-coding.kotlin
Normal file
52
Task/Huffman-coding/Kotlin/huffman-coding.kotlin
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
abstract class HuffmanTree(var freq: Int) : Comparable<HuffmanTree> {
|
||||
override fun compareTo(other: HuffmanTree) = freq - other.freq
|
||||
}
|
||||
|
||||
class HuffmanLeaf(freq: Int, var value: Char) : HuffmanTree(freq)
|
||||
|
||||
class HuffmanNode(var left: HuffmanTree, var right: HuffmanTree) : HuffmanTree(left.freq + right.freq)
|
||||
|
||||
fun buildTree(charFreqs: IntArray) : HuffmanTree {
|
||||
val trees = PriorityQueue<HuffmanTree>()
|
||||
|
||||
charFreqs.forEachIndexed { index, freq ->
|
||||
if(freq > 0) trees.offer(HuffmanLeaf(freq, index.toChar()))
|
||||
}
|
||||
|
||||
assert(trees.size > 0)
|
||||
while (trees.size > 1) {
|
||||
val a = trees.poll()
|
||||
val b = trees.poll()
|
||||
trees.offer(HuffmanNode(a, b))
|
||||
}
|
||||
|
||||
return trees.poll()
|
||||
}
|
||||
|
||||
fun printCodes(tree: HuffmanTree, prefix: StringBuffer) {
|
||||
when(tree) {
|
||||
is HuffmanLeaf -> println("${tree.value}\t${tree.freq}\t$prefix")
|
||||
is HuffmanNode -> {
|
||||
//traverse left
|
||||
prefix.append('0')
|
||||
printCodes(tree.left, prefix)
|
||||
prefix.deleteCharAt(prefix.lastIndex)
|
||||
//traverse right
|
||||
prefix.append('1')
|
||||
printCodes(tree.right, prefix)
|
||||
prefix.deleteCharAt(prefix.lastIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val test = "this is an example for huffman encoding"
|
||||
|
||||
val maxIndex = test.max()!!.toInt() + 1
|
||||
val freqs = IntArray(maxIndex) //256 enough for latin ASCII table, but dynamic size is more fun
|
||||
test.forEach { freqs[it.toInt()] += 1 }
|
||||
|
||||
val tree = buildTree(freqs)
|
||||
println("SYMBOL\tWEIGHT\tHUFFMAN CODE")
|
||||
printCodes(tree, StringBuffer())
|
||||
}
|
||||
91
Task/Huffman-coding/Oberon-2/huffman-coding.oberon-2
Normal file
91
Task/Huffman-coding/Oberon-2/huffman-coding.oberon-2
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
MODULE HuffmanEncoding;
|
||||
IMPORT
|
||||
Object,
|
||||
PriorityQueue,
|
||||
Strings,
|
||||
Out;
|
||||
TYPE
|
||||
Leaf = POINTER TO LeafDesc;
|
||||
LeafDesc = RECORD
|
||||
(Object.ObjectDesc)
|
||||
c: CHAR;
|
||||
END;
|
||||
|
||||
Inner = POINTER TO InnerDesc;
|
||||
InnerDesc = RECORD
|
||||
(Object.ObjectDesc)
|
||||
left,right: Object.Object;
|
||||
END;
|
||||
|
||||
VAR
|
||||
str: ARRAY 128 OF CHAR;
|
||||
i: INTEGER;
|
||||
f: ARRAY 96 OF INTEGER;
|
||||
q: PriorityQueue.Queue;
|
||||
a: PriorityQueue.Node;
|
||||
b: PriorityQueue.Node;
|
||||
c: PriorityQueue.Node;
|
||||
h: ARRAY 64 OF CHAR;
|
||||
|
||||
PROCEDURE NewLeaf(c: CHAR): Leaf;
|
||||
VAR
|
||||
x: Leaf;
|
||||
BEGIN
|
||||
NEW(x);x.c := c; RETURN x
|
||||
END NewLeaf;
|
||||
|
||||
PROCEDURE NewInner(l,r: Object.Object): Inner;
|
||||
VAR
|
||||
x: Inner;
|
||||
BEGIN
|
||||
NEW(x); x.left := l; x.right := r; RETURN x
|
||||
END NewInner;
|
||||
|
||||
|
||||
PROCEDURE Preorder(n: Object.Object; VAR x: ARRAY OF CHAR);
|
||||
BEGIN
|
||||
IF n IS Leaf THEN
|
||||
Out.Char(n(Leaf).c);Out.String(": ");Out.String(h);Out.Ln
|
||||
ELSE
|
||||
IF n(Inner).left # NIL THEN
|
||||
Strings.Append("0",x);
|
||||
Preorder(n(Inner).left,x);
|
||||
Strings.Delete(x,(Strings.Length(x) - 1),1)
|
||||
END;
|
||||
IF n(Inner).right # NIL THEN
|
||||
Strings.Append("1",x);
|
||||
Preorder(n(Inner).right,x);
|
||||
Strings.Delete(x,(Strings.Length(x) - 1),1)
|
||||
END
|
||||
END
|
||||
END Preorder;
|
||||
|
||||
BEGIN
|
||||
str := "this is an example for huffman encoding";
|
||||
|
||||
(* Collect letter frecuencies *)
|
||||
i := 0;
|
||||
WHILE str[i] # 0X DO INC(f[ORD(CAP(str[i])) - ORD(' ')]);INC(i) END;
|
||||
|
||||
(* Create Priority Queue *)
|
||||
NEW(q);q.Clear();
|
||||
|
||||
(* Insert into the queue *)
|
||||
i := 0;
|
||||
WHILE (i < LEN(f)) DO
|
||||
IF f[i] # 0 THEN
|
||||
q.Insert(f[i]/Strings.Length(str),NewLeaf(CHR(i + ORD(' '))))
|
||||
END;
|
||||
INC(i)
|
||||
END;
|
||||
|
||||
(* create tree *)
|
||||
WHILE q.Length() > 1 DO
|
||||
q.Remove(a);q.Remove(b);
|
||||
q.Insert(a.w + b.w,NewInner(a.d,b.d));
|
||||
END;
|
||||
|
||||
(* tree traversal *)
|
||||
h[0] := 0X;q.Remove(c);Preorder(c.d,h);
|
||||
|
||||
END HuffmanEncoding.
|
||||
|
|
@ -1,17 +1,13 @@
|
|||
sub huffman ($s) {
|
||||
my $de = $s.chars;
|
||||
my @q = $s.comb.classify({$_}).map({[+.value / $de, .key]}).sort;
|
||||
while @q > 1 {
|
||||
my ($a,$b) = @q.splice(0,2);
|
||||
@q = sort flat $[$a[0] + $b[0], [$a[1], $b[1]]], @q;
|
||||
sub huffman (%frequencies) {
|
||||
my @queue = %frequencies.map({ [.value, .key] }).sort;
|
||||
while @queue > 1 {
|
||||
given @queue.splice(0, 2) -> ([$freq1, $node1], [$freq2, $node2]) {
|
||||
@queue = (|@queue, [$freq1 + $freq2, [$node1, $node2]]).sort;
|
||||
}
|
||||
}
|
||||
sort *.value, gather walk @q[0][1], '';
|
||||
hash gather walk @queue[0][1], '';
|
||||
}
|
||||
|
||||
multi walk (@node, $prefix) {
|
||||
walk @node[0], $prefix ~ 1;
|
||||
walk @node[1], $prefix ~ 0;
|
||||
}
|
||||
multi walk ($node, $prefix) { take $node => $prefix }
|
||||
|
||||
say .perl for huffman('this is an example for huffman encoding');
|
||||
multi walk ($node, $prefix) { take $node => $prefix; }
|
||||
multi walk ([$node1, $node2], $prefix) { walk $node1, $prefix ~ '0';
|
||||
walk $node2, $prefix ~ '1'; }
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
my $str = 'this is an example for huffman encoding';
|
||||
my %enc = huffman $str;
|
||||
my %dec = %enc.invert;
|
||||
say $str;
|
||||
my $huf = %enc{$str.comb}.join;
|
||||
say $huf;
|
||||
my $rx = join('|', map { "'" ~ .key ~ "'" }, %dec);
|
||||
$rx = EVAL '/' ~ $rx ~ '/';
|
||||
say $huf.subst(/<$rx>/, -> $/ {%dec{~$/}}, :g);
|
||||
sub huffman (%frequencies) {
|
||||
my @queue = %frequencies.map: { .value => (hash .key => '') };
|
||||
while @queue > 1 {
|
||||
@queue.=sort;
|
||||
my $x = @queue.shift;
|
||||
my $y = @queue.shift;
|
||||
@queue.push: ($x.key + $y.key) => hash $x.value.deepmap('0' ~ *),
|
||||
$y.value.deepmap('1' ~ *);
|
||||
}
|
||||
@queue[0].value;
|
||||
}
|
||||
|
|
|
|||
3
Task/Huffman-coding/Perl-6/huffman-coding-3.pl6
Normal file
3
Task/Huffman-coding/Perl-6/huffman-coding-3.pl6
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
for huffman 'this is an example for huffman encoding'.comb.Bag {
|
||||
say "'{.key}' : {.value}";
|
||||
}
|
||||
10
Task/Huffman-coding/Perl-6/huffman-coding-4.pl6
Normal file
10
Task/Huffman-coding/Perl-6/huffman-coding-4.pl6
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
my $original = 'this is an example for huffman encoding';
|
||||
|
||||
my %encode-key = huffman $original.comb.Bag;
|
||||
my %decode-key = %encode-key.invert;
|
||||
my @codes = %decode-key.keys;
|
||||
|
||||
my $encoded = $original.subst: /./, { %encode-key{$_} }, :g;
|
||||
my $decoded = $encoded .subst: /@codes/, { %decode-key{$_} }, :g;
|
||||
|
||||
.say for $original, $encoded, $decoded;
|
||||
61
Task/Huffman-coding/PowerShell/huffman-coding.psh
Normal file
61
Task/Huffman-coding/PowerShell/huffman-coding.psh
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
function Get-HuffmanEncodingTable ( $String )
|
||||
{
|
||||
# Create leaf nodes
|
||||
$ID = 0
|
||||
$Nodes = [char[]]$String |
|
||||
Group-Object |
|
||||
ForEach { $ID++; $_ } |
|
||||
Select @{ Label = 'Symbol' ; Expression = { $_.Name } },
|
||||
@{ Label = 'Count' ; Expression = { $_.Count } },
|
||||
@{ Label = 'ID' ; Expression = { $ID } },
|
||||
@{ Label = 'Parent' ; Expression = { 0 } },
|
||||
@{ Label = 'Code' ; Expression = { '' } }
|
||||
|
||||
# Grow stems under leafs
|
||||
ForEach ( $Branch in 2..($Nodes.Count) )
|
||||
{
|
||||
# Get the two nodes with the lowest count
|
||||
$LowNodes = $Nodes | Where Parent -eq 0 | Sort Count | Select -First 2
|
||||
|
||||
# Create a new stem node
|
||||
$ID++
|
||||
$Nodes += '' |
|
||||
Select @{ Label = 'Symbol' ; Expression = { '' } },
|
||||
@{ Label = 'Count' ; Expression = { $LowNodes[0].Count + $LowNodes[1].Count } },
|
||||
@{ Label = 'ID' ; Expression = { $ID } },
|
||||
@{ Label = 'Parent' ; Expression = { 0 } },
|
||||
@{ Label = 'Code' ; Expression = { '' } }
|
||||
|
||||
# Put the two nodes in the new stem node
|
||||
$LowNodes[0].Parent = $ID
|
||||
$LowNodes[1].Parent = $ID
|
||||
|
||||
# Assign 0 and 1 to the left and right nodes
|
||||
$LowNodes[0].Code = '0'
|
||||
$LowNodes[1].Code = '1'
|
||||
}
|
||||
|
||||
# Assign coding to nodes
|
||||
ForEach ( $Node in $Nodes[($Nodes.Count-2)..0] )
|
||||
{
|
||||
$Node.Code = ( $Nodes | Where ID -eq $Node.Parent ).Code + $Node.Code
|
||||
}
|
||||
|
||||
$EncodingTable = $Nodes | Where { $_.Symbol } | Select Symbol, Code | Sort Symbol
|
||||
return $EncodingTable
|
||||
}
|
||||
|
||||
# Get table for given string
|
||||
$String = "this is an example for huffman encoding"
|
||||
$HuffmanEncodingTable = Get-HuffmanEncodingTable $String
|
||||
|
||||
# Display table
|
||||
$HuffmanEncodingTable | Format-Table -AutoSize
|
||||
|
||||
# Encode string
|
||||
$EncodedString = $String
|
||||
ForEach ( $Node in $HuffmanEncodingTable )
|
||||
{
|
||||
$EncodedString = $EncodedString.Replace( $Node.Symbol, $Node.Code )
|
||||
}
|
||||
$EncodedString
|
||||
|
|
@ -12,8 +12,8 @@ Structure ztree
|
|||
right.l
|
||||
EndStructure
|
||||
|
||||
Dim memc.c(0)
|
||||
memc()=@SampleString
|
||||
Dim memc.c(datalen)
|
||||
CopyMemory(@SampleString, @memc(0), datalen * SizeOf(Character))
|
||||
|
||||
Dim tree.ztree(255)
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ For i=0 To datalen-1
|
|||
tree(memc(i))\ischar=1
|
||||
Next
|
||||
|
||||
SortStructuredArray(tree(),#PB_Sort_Descending,OffsetOf(ztree\number),#PB_Sort_Character)
|
||||
SortStructuredArray(tree(),#PB_Sort_Descending,OffsetOf(ztree\number),#PB_Integer)
|
||||
|
||||
For i=0 To 255
|
||||
If tree(i)\number=0
|
||||
|
|
|
|||
43
Task/Huffman-coding/Scala/huffman-coding-2.scala
Normal file
43
Task/Huffman-coding/Scala/huffman-coding-2.scala
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// this version uses immutable data only, recursive functions and pattern matching
|
||||
object Huffman {
|
||||
sealed trait Tree[+A]
|
||||
case class Leaf[A](value: A) extends Tree[A]
|
||||
case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]
|
||||
|
||||
// recursively build the binary tree needed to Huffman encode the text
|
||||
def merge(xs: List[(Tree[Char], Int)]): List[(Tree[Char], Int)] = {
|
||||
if (xs.length == 1) xs else {
|
||||
val l = xs.head
|
||||
val r = xs.tail.head
|
||||
val merged = (Branch(l._1, r._1), l._2 + r._2)
|
||||
merge((merged :: xs.drop(2)).sortBy(_._2))
|
||||
}
|
||||
}
|
||||
|
||||
// recursively search the branches of the tree for the required character
|
||||
def contains(tree: Tree[Char], char: Char): Boolean = tree match {
|
||||
case Leaf(c) => if (c == char) true else false
|
||||
case Branch(l, r) => contains(l, char) || contains(r, char)
|
||||
}
|
||||
|
||||
// recursively build the path string required to traverse the tree to the required character
|
||||
def encodeChar(tree: Tree[Char], char: Char): String = {
|
||||
def go(tree: Tree[Char], char: Char, code: String): String = tree match {
|
||||
case Leaf(_) => code
|
||||
case Branch(l, r) => if (contains(l, char)) go(l, char, code + '0') else go(r, char, code + '1')
|
||||
}
|
||||
go(tree, char, "")
|
||||
}
|
||||
|
||||
def main(args: Array[String]) {
|
||||
val text = "this is an example for huffman encoding"
|
||||
// transform the text into a list of tuples.
|
||||
// each tuple contains a Leaf node containing a unique character and an Int representing that character's weight
|
||||
val frequencies = text.groupBy(chars => chars).mapValues(group => group.length).toList.map(x => (Leaf(x._1), x._2)).sortBy(_._2)
|
||||
// build the Huffman Tree for this text
|
||||
val huffmanTree = merge(frequencies).head._1
|
||||
// output the resulting character codes
|
||||
println("Char\tWeight\tCode")
|
||||
frequencies.foreach(x => println(x._1.value + "\t" + x._2 + s"/${text.length}" + s"\t${encodeChar(huffmanTree, x._1.value)}"))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue