数据压缩算法之哈夫曼编码(HUFFMAN)的实现
HUFFMAN编码可以很有效的压缩数据,通常可以压缩20%到90%的空间(算法导论)。具体的压缩率取决于数据的特性(词频)。如果采取标准的语料库进行编码,一般可以得到比较满意的编码结果(对不同文件产生不同压缩率的折中方法)。
本文采取对单独一个文件进行编码的方式来演示此压缩算法的使用。
分为下面几个步骤:
1.统计词频数据
2.词频数据转换成HUFFMAN算法能够处理的类型(本文为HuffmanNode,内部有存储词频和树节点的结构)
(1)由输入的HuffmanNode[]数组创建最小优先级队列
(2)依次取出队列中的每两个节点,然后由此两个节点构造一个新的节点,然后在重新插入回队列。直到队列中只剩唯一一个节点。
此节点为编码树的根节点。
(3)依次遍历原来输入的每个HUFFMAN节点,得到每个字符的对应编码(压缩使用)。
(4)解码方式,依次输入0/1字符码到算法,算法遍历产生的编码树,如果有返回字符,则得到解码字符。
词频统计的实现:
public class FrequencyCounter
{
public IEnumerable<KeyValuePair<char, int>> MapReduce(string str)
{
//the GroupBy method is acting as the map,
//while the Select method does the job of reducing the intermediate results into the final list of results.
var wordOccurrences = str
.GroupBy(w => w)
.Select(intermediate => new
{
Key = intermediate.Key,
Value = intermediate.Sum(w => )
})
.OrderBy(kvp => kvp.Value);
IEnumerable<KeyValuePair<char, int>> kvps = from wo in wordOccurrences select new KeyValuePair<char, int>(wo.Key, wo.Value);
return kvps;
}
}
MapReduce
HUFFMAN编码类的实现:
public class Huffman
{
private List<HuffmanNode> originalNodes;
private HuffmanNode rootNode;
public Huffman(IEnumerable<KeyValuePair<char, int>> kvps)
{
//保存原始数据
var tmpOriginalNodes = from kvp in kvps select new HuffmanNode(kvp.Key, kvp.Value);
//创建最小优先队列,并输入数据
MinPriorityQueue<HuffmanNode> minQueue = new MinPriorityQueue<HuffmanNode>();
originalNodes = new List<HuffmanNode>();
foreach (var node in tmpOriginalNodes)
{
originalNodes.Add(node);
minQueue.Insert(node);
}
//建造编码树,并取得编码树的根节点
while (!minQueue.IsEmpty)
{
HuffmanNode left = minQueue.ExtractMin();
if (minQueue.IsEmpty)
{
rootNode = left;
break;
}
HuffmanNode right = minQueue.ExtractMin();
HuffmanNode newNode = new HuffmanNode(null, left.Value + right.Value, left, right);
left.Parent = newNode;
right.Parent = newNode;
minQueue.Insert(newNode);
}
}
//只接受单个char的加密
public string Encode(char sourceChar)
{
HuffmanNode hn = originalNodes.FirstOrDefault(n => n.Key == sourceChar);
if (hn == null) return null;
HuffmanNode parent = hn.Parent;
StringBuilder rtn = new StringBuilder();
while (parent != null)
{
if (Object.ReferenceEquals(parent.Left, hn))//左孩子,编码为0
{
rtn.Insert(, "", );
}
else//右孩子,编码为1
{
rtn.Insert(, "", );
}
hn = parent;
parent = parent.Parent;
}
return rtn.ToString();
}
//只接受一个字符的解码输出
public bool Decode(string string01, out char? output)
{
HuffmanNode tmpNode = rootNode;
char[] chars = string01.Trim().ToCharArray();
for (int i = ; i < chars.Count(); i++)
{
if (chars[i] == '') tmpNode = tmpNode.Left;
if (chars[i] == '') tmpNode = tmpNode.Right;
}
if (tmpNode != null && tmpNode.Left == null && tmpNode.Right==null)
{
output = tmpNode.Key;
return true;
}
else
{
output = null;
return false;
}
} class HuffmanNode : IHeapValue
{
public HuffmanNode(char? key, int value, HuffmanNode left = null, HuffmanNode right = null)
{
this.Left = left;
this.Right = right;
this.Key = key;
this.Value = value;
}
public HuffmanNode Left { get; private set; }
public HuffmanNode Right { get; private set; }
public HuffmanNode Parent { get; set; }
public char? Key { get; private set; }
public int Value { get; set; }
}
}
对文本进行编码的用法:
FrequencyCounter fc = new FrequencyCounter();
var kvps = fc.MapReduce(这里是你的文本);
hm = new Huffman(kvps);
StringBuilder sb = new StringBuilder();
string ori =这里是你的文本;
char[] chararray = ori.ToCharArray();
for (int i = ; i < chararray.Length; i++)
{
sb.Append(hm.Encode(chararray[i]));
}
对编码进行解码:
string bstr =你的编码后的文本;
StringBuilder sb = new StringBuilder();
char? outchar = null;
string tmpStr = null;
for (int i = ; i < bstr.Length; i++)
{
tmpStr = tmpStr + bstr[i];
if (hm.Decode(tmpStr, out outchar))
{
tmpStr = null;
sb.Append(outchar);
}
}
测试效果,可以看到压缩效果还是很明显的:

完毕。
作者:Andy Zeng
欢迎任何形式的转载,但请务必注明出处。
http://www.cnblogs.com/andyzeng/p/3703321.html
数据压缩算法之哈夫曼编码(HUFFMAN)的实现的更多相关文章
- 数据压缩之经典——哈夫曼编码(Huffman)
(笔记图片截图自课程Image and video processing: From Mars to Hollywood with a stop at the hospital的教学视频,使用时请注意 ...
- 赫夫曼\哈夫曼\霍夫曼编码 (Huffman Tree)
哈夫曼树 给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的结点离 ...
- 哈夫曼编码(Huffman coding)的那些事,(编码技术介绍和程序实现)
前言 哈夫曼编码(Huffman coding)是一种可变长的前缀码.哈夫曼编码使用的算法是David A. Huffman还是在MIT的学生时提出的,并且在1952年发表了名为<A Metho ...
- 采用霍夫曼编码(Huffman)画出字符串各字符编码的过程并求出各字符编码 --多媒体技术与应用
题目:有一个字符串:cabcedeacacdeddaaaba,问题: (1)采用霍夫曼编码画出编码的过程,并写出各字符的编码 (2)根据求得的编码,求得各编码需要的总位数 (3)求出整个字符串总编码长 ...
- 霍夫曼编码(Huffman)
题目:有一个字符串:cabcedeacacdeddaaaba,问题: (1)采用霍夫曼编码画出编码的过程,并写出各字符的编码 (2)根据求得的编码,求得各编码需要的总位数 (3)求出整个字符串总编码长 ...
- Python 算法(2) 哈夫曼编码 Huffman Encoding
这个问题原始是用来实现一个可变长度的编码问题,但可以总结成这样一个问题,假设我们有很多的叶子节点,每个节点都有一个权值w(可以是任何有意义的数值,比如它出现的概率),我们要用这些叶子节点构造一棵树,那 ...
- 霍夫曼编码(Huffman Coding)
霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种. 霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符 ...
- 哈夫曼编码的理解(Huffman Coding)
哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,可变字长编码(VLC)的一种.Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最 ...
- HDU2527 哈夫曼编码
Safe Or Unsafe Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
随机推荐
- HTML(1)简介
"超"文本标记语言--HTML 文本,是指书面语言的表现形式. 百度百科 说白了,文本就是你能看得到的字,不论是纸上的还是屏幕上的,都是文本.文本就是用来记录信息一种形式. 那么, ...
- spring第一章
spring第一章 一.概述 Spring是一个开源框架,它由Rod Johnson创建.它是为了解决企业应用开发的复杂性而创建的.Spring使用基本的JavaBean来完成以前只可能由EJB完成的 ...
- Python 数据图表工具的比较
Python 的科学栈相当成熟,各种应用场景都有相关的模块,包括机器学习和数据分析.数据可视化是发现数据和展示结果的重要一环,只不过过去以来,相对于 R 这样的工具,发展还是落后一些. 幸运的是,过去 ...
- PSP Daily软件Alpha版本——基于spec评论
题目要求:每个小组评论其他小组Alpha发布作品的软件功能说明书.要求和提交在[https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/122 ...
- 冲刺ing-7
第七次Scrum冲刺 队员完成的任务 队员 完成任务 吴伟华 Leangoo的看板截图,燃尽图 蔺皓雯 编写博客 蔡晨旸 进行测试 曾茜 界面设计 鲁婧楠 界面前后端 杨池宇 界面前后端 项目的发布说 ...
- 按照Right-BICEP要求设计的测试用例
测试用例: 测试方法:Right-BICEP 测试要求: Right-结果是否正确? B-是否所有的边界条件都是正确的? P-是否满足性能要求? 题目是否有重复? 数量是否可定制? 数值范围是否可定制 ...
- 软件工程 speedsnail 第二次冲刺10
20150527 完成任务:蜗牛碰到线后速度方向的调整:已经基本实现多方向的反射: 遇到问题: 问题1 反射角的问题 解决1 利用tan()三角函数 明日任务: 大总结.找到新问题.布置下一次冲刺方案
- huawei oceanstor
华为产品:OceanStor 6000 V3系列 OceanStor 6800 V3 网页登入设备页面:https+ip+端口 资源分配界面: 首页: wwn为2100xxxxxxxx47e4,设 ...
- QJsonDocument实现Qt下JSON文档读写
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QJsonDocument实现Qt下JSON文档读写 本文地址:http://tech ...
- IIS部署时未能加载程序集"System.Web.Http.WebHost"解决方法
问题如下 服务器没有安装MVC,下载以下dll覆盖到bin目录下,即可免安装运行程序. 下载地址:https://pan.baidu.com/s/1mhCo5mS