static string decode(bool[] encoded_text, Node node) { Node node_a = node; StringBuilder builder = new StringBuilder(); for (int i = 0; i < encoded_text.Length;) { while (!node.IsEnd) { if (encoded_text[i++]) node = node.B; else node = node.A; } builder.Append(node.Chars[0]); node = node_a; } return builder.ToString(); }
static bool[] encode(string text, out Node node) { char[] chars; int[] counts; calc(text, out chars, out counts); sort(chars, counts); node = tree(chars, counts); bool[] encoded_text = new bool[0]; for (int i = 0; i < text.Length; i++) { bool[] code = calc_code(node, text[i]); int length = encoded_text.Length; Array.Resize<bool>(ref encoded_text, length + code.Length); Array.Copy(code, 0, encoded_text, length, code.Length); } return encoded_text; }
public void Build(string source) { foreach (Char t in source) { if (!Frequencies.ContainsKey(t)) { Frequencies.Add(t, 0); } Frequencies[t]++; } Debug.Assert( Frequencies != null, "Frequencies != null" ); foreach (KeyValuePair<char, int> symbol in Frequencies) nodes.Add( new Node() { Symbol = symbol.Key, Frequency = symbol.Value } ); while (nodes.Count > 1) { List<Node> orderedNodes = nodes.OrderBy(node => node.Frequency).ToList(); if (orderedNodes.Count >= 2) { // Take first two items List<Node> taken = orderedNodes.Take(2).ToList(); // Create a parent node by combining the frequencies Node parent = new Node { Frequency = taken[0].Frequency + taken[1].Frequency, Left = taken[0], Right = taken[1], Symbol = '*' }; nodes.Remove(taken[0]); nodes.Remove(taken[1]); nodes.Add(parent); } this.Root = nodes.FirstOrDefault(); } }
static bool[] calc_code(Node node, char c) { bool[] code = new bool[0]; while (true) { if (node.IsEnd) break; Array.Resize<bool>(ref code, code.Length + 1); if (node.A.Chars.Contains(c)) { node = node.A; code[code.Length - 1] = false; } else { node = node.B; code[code.Length - 1] = true; } } return code; }
public Node(Node a, Node b) { this.a = a; this.b = b; this.value = a.Value + b.Value; this.Chars = new char[a.Chars.Length + b.Chars.Length]; Array.Copy(a.Chars, 0, this.chars, 0, a.Chars.Length); Array.Copy(b.Chars, 0, this.chars, a.Chars.Length, b.Chars.Length); }
static Node tree(char[] chars, int[] counts) { Node[] nodes = new Node[chars.Length]; for (int i = 0; i < nodes.Length; i++) nodes[i] = new Node(chars[i], counts[i]); do { int a_index = min_node(nodes, -1); int b_index = min_node(nodes, a_index); Node c = new Node(nodes[a_index], nodes[b_index]); nodes[a_index] = c; nodes[b_index] = null; int count = 0; for (int i = 0; i < nodes.Length; i++) if (nodes[i] != null) count++; if (count == 1) break; } while (true); Node node = null; for (int i = 0; i < nodes.Length; i++) if (nodes[i] != null) { node = nodes[i]; break; } return node; }
static int min_node(Node[] nodes, int ignore) { Node node = null; int index = 0; for (int i = 0; i < nodes.Length; i++) if (nodes[i] != null && i != ignore) { node = nodes[i]; index = i; break; } for (int i = 0; i < nodes.Length; i++) if (nodes[i] != null && i != ignore && nodes[i].Value < node.Value) { node = nodes[i]; index = i; } return index; }
public bool IsLeaf(Node node) { return (node.Left == null && node.Right == null); }