C# Huffman编译码细节
来源:互联网 发布:网络主播服装 编辑:程序博客网 时间:2024/06/18 06:59
最近用C#写huffman编译码程序的时候发现了一些问题,这里整理一下(新手勿喷): [文件为非中文文件]
1.文件中出现的各个字符的出现频率的取得。其实现方法如下:
1.1很容易想到一种一个个(Streamreader.read)读入或者一行行(Streamreader.readLine)读入或者整个文本读入(Streamreader.readToEnd),再进行匹配。可以预见,这个方法非常慢,对于几百kb的txt或者几Mb的txt会很慢。
1.2这里看到一种方法是读入后,进行整个文本的查找,替换成空,前后的字符串长度的变化即为这个字符出现的频次。
c2 = str.Length - str.Replace("A", String.Empty).Length;
1.3 根据1.2,想到另外一种方法。即要查找的字符作为分隔符,将原字符串分隔为多个子串,然后求子串的数目即可
c3 = str.Split(new char[] { 'A' }).Length - 1;统计整个文本的字符时应注意以下问题:
- 注意读入文本时所用的方法的异同;read()返回对应的ASCII,readLine()遇到“\n”,“\r\n”等会对文本中出现的换行有影响,建议使用整个文本读入,速度也快。
- 由于我是静态开辟的数组存储对应的字符频次,所以使用的是ASCII表,这里当然会有一些字符对应的频次是0,故这些要去掉,不去掉的话对后面的Huffman编码影响较大,个人建议使用动态开辟的;
//通过遍历进行Hufman编码,并输出 public void traverse(Node root) { if (root != null) { if (root.character != "NO CHAR") { this.code[this.i, 0] = root.character; this.code[this.i, 1] = root.code; this.i++; } if (root.left != null) { root.left.code = root.left.parent.code + "0"; traverse(root.left); } if (root.right != null) { root.right.code = root.left.parent.code + "1"; traverse(root.right); } } }3.对文件进行Huffman编码。
很容易想到每个字符对应每个Huffman码,那么直接替换就可以了。但是要注意0和1的特殊性,所以这里要对0和1在文本的字符进行优先处理,而且要注意到两个之间任意一个先替换都会影响后一个的替换。所以只能是将文本读入的信息进行一次0和1处理(我目前只想到了这个,不过貌似可以记录已经编码的字符位置,然后来实现)。
对于其他非0和1字符,直接进行全文替换就可以了。
//按照编码顺序一行行编码,实为按照编码替换public void make_string() { this.m_streamReader.BaseStream.Seek(0, SeekOrigin.Begin);// 从数据流中读取每一行,直到文件的最后一行 int strLine; //查到0和1的编码 string code0=null,code1=null; for(int i=0;i<this.code.GetLength(0);i++) { if(this.code[i,0]=="0") code0=this.code[i,1]; if(this.code[i,0]=="1") code1=this.code[i,1]; }while (this.m_streamReader.Peek() >= 0) { strLine = this.m_streamReader.Read(); switch (strLine) { case 48: this.s += code0; break; case 49: this.s += code1; break; default: this.s += (char)strLine; break; } } this.m_streamReader.Close(); this.fs1.Close(); for (int i = 0; i < this.code.GetLength(0); i++) if ((this.code[i, 0]!= "0") && (this.code[i, 0]!= "1")) this.s = this.s.Replace(this.code[i, 0], this.code[i, 1]); }4.Huffman译码的实现。根据输入的文本信息01流,按照Huffman树进行依次查找。这里直接贴代码
//通过遍历进行Huffman译码,并输出 public Node decode(int a,Node root) { Node node=null; if (root != null) { if (a == 48)//左子树 { if (!root.left.isLeaf()) { node = root.left; } else { this.txt += root.left.character; node = this.root; } } if (a == 49) { if (!root.right.isLeaf()) { node = root.right; } else { this.txt += root.right.character; node = this.root; } } } return node; }注意Huffman树随着源文件的变大,编译码的速度会很慢,很多时候代码本身还会出现内存溢出等各种错误,所以就要求仔细分析代码的效率。
0 0
- C# Huffman编译码细节
- 数据结构实习之Huffman编译码(四)
- Huffman编码与译码
- 数据结构Huffman编码译码
- Huffman Code 编码译码
- huffman编码和译码实现
- RM码编译码
- 重复码编译码
- HDB3编译码原理
- Viterbi编译码
- TFCI码的编译码
- 模拟编码译码(huffman编码应用)
- huffman编解码源代码
- 【数据压缩】Huffman编解码
- Huffman编解码
- Huffman编解码
- Huffman编解码
- Huffman编解码
- What's the returned value of javascript constructor function
- C++ is a bitch, But i Love it!(更新,已无爱。)
- c++中explicit
- 决策树与R语言(RPART)
- GCC编译选项补充
- C# Huffman编译码细节
- 杭电OJ(HDOJ)1010题:Tempter of the Bone(DFS,迷宫求解)
- 杨辉三角
- linux snprintf获取字符串中的某一段的长度问题
- uva 10487
- hdu-1282-回文数猜想( 存int类型操作 )
- Hash Table 开放寻址处理冲突
- OpenWRT定时关闭WIFI
- JAVA - 类和对象