using System; using System.Collections.Generic; using System.Linq; namespace iWareCommon.Common.Entity { public class Huffman { /// /// 原始的编码字符的集合 /// private char[] mDict; /// /// 原始编码字符中实际使用到的字符集(用于需要编码的字符串中的字符小于所定义的字符集) /// private char[] mCntDict; /// /// 无参构造函数 /// public Huffman() { this.mDict = new char[0]; mCntDict = mDict; } /// /// 构造函数,给定Haffman字符的字段集合 /// /// public Huffman(char[] dict) { this.mDict = dict.Distinct().ToArray(); mCntDict = mDict; } /// /// 构造函数,给定Haffman字符的字段集合 /// public Huffman(string dict) { this.mDict = dict.ToCharArray().Distinct().ToArray(); mCntDict = mDict; } /// /// 将字符串转Huffman码,并且生成字符转换的关键字典集 /// /// 导出的关键字字典 /// 需要编码的huffman集合 /// public string StringToHuffmanCode(out Dictionary key, string str) { var tmps = GetWeightArray(str); var tree = CreateHuffmanTree(tmps); key = CreateHuffmanCode("", tree); return ToHuffmanCode(str, key); } /// /// 关键关键字典将编码还原 /// /// /// /// public string ToText(string code, Dictionary key) { string result = ""; for (int i = 0; i < code.Length; ) { foreach (var item in key) { if (code[i] == item.Value[0] && item.Value.Length + i <= code.Length) { char[] tmpArr = new char[item.Value.Length]; Array.Copy(code.ToCharArray(), i, tmpArr, 0, tmpArr.Length); if (new string(tmpArr) == item.Value) { result += item.Key; i += item.Value.Length; break; } } } } return result; } /// /// 计算每个字符串的权重 /// /// /// private Node[] GetWeightArray(string str) { var nodes = new List(); var charArr = str.ToCharArray(); if (charArr.Length < mDict.Length) { mCntDict = new char[charArr.Length]; Array.Copy(mDict, 0, mCntDict, 0, charArr.Length); } while (charArr.Length > 0) { var tmp = charArr.Where(m => m == charArr[0]).ToArray(); nodes.Add(new Node(tmp.Length, tmp.First())); charArr = charArr.Where(m => m != tmp.First()).ToArray(); } return nodes.ToArray(); } /// /// 生成Haffman树的算法 /// /// 原始的节点集合 /// 生成好的Haffman树 private Node CreateHuffmanTree(Node[] nodes) { if (nodes.Length <= mCntDict.Length) { var node = new Node(0, '\0'); node.Children = nodes; foreach (var n in nodes) { node.Weight += n.Weight; } return node; } Array.Sort(nodes); var newNode = new Node(0, '\0'); newNode.Children = new Node[mCntDict.Length]; for (int i = nodes.Length - 1, j = 0; i >= 0; i--, j++) { if (j >= mCntDict.Length) { break;} newNode.Weight += nodes[i].Weight; newNode.Children[j] = nodes[i]; } var newNodes = new Node[nodes.Length - mCntDict.Length + 1]; Array.Copy(nodes, 0, newNodes, 0, newNodes.Length - 1); newNodes[newNodes.Length - 1] = newNode; return CreateHuffmanTree(newNodes); } /// /// 生成关键字典集 /// /// 默认填充字符 /// /// private Dictionary CreateHuffmanCode(string code, Node hTree) { var key = new Dictionary(); if (hTree.Children == null) { key.Add(hTree.Key, code); } else { for (int i = 0; i < hTree.Children.Length; i++) { var tmpDict = CreateHuffmanCode(code + mCntDict[i], hTree.Children[i]); foreach (var item in tmpDict) { key.Add(item.Key, item.Value); } } } return key; } /// /// 关键生成的数将字符转出Haffman码 /// /// /// /// private string ToHuffmanCode(string source, Dictionary key) { string result = ""; for (int i = 0; i < source.Length; i++) { result += key.First(m => m.Key == source[i]).Value; } return result; } } public class Node : IComparable { public Node[] Children { get; set; } public int Weight { get; set; } public char Key { get; set; } public Node() { } public Node(int weight, char value) { this.Weight = weight; this.Key = value; } /// /// 关键权重降序排序 /// /// /// public int CompareTo(object obj) { var tmp = obj as Node; if (tmp.Weight > this.Weight) { return 1; } if (tmp.Weight < this.Weight) { return -1; } return 0; } } }