C++ 实现Huffman编译码器
来源:互联网 发布:数据库nvl 编辑:程序博客网 时间:2024/05/29 12:32
实现功能
1.实现自动统计输入文本的字符个数以及各字符的权值;
2.实现输入字符及各权值进行Huffman编码;
3.实现从文档保存数据及读取数据;
4.各字符及其权值是由单链表的形式存储的;
5.译码是每50个01字符输出换行;
**注**Huffman树的建立是通过课本方法建立,其方式就不多说了。
代码实现
huffman.cpp
#include "huffman3.h"void Huffman :: readtext(char *file){ //读取文件中的数据,包括空格 indata.open(file); if (! indata) { cout << "ERROR!" << endl; } char temp[100]; indata.getline(temp, 100); text += temp;}void Huffman :: savetext(char *file){ //保存数据到文件 outdata.open(file); if (! outdata) { cout << "ERROR" << endl; } outdata << text;}void Huffman :: readcode(char *file){ //读取代码 indata.open(file); indata >> huffmancode; }/*void Huffman::ReadCodeFromFile(char *filename){ //读取代码(这个也可以用) ifstream infile(filename); if (!infile) { cerr << "无法打开文件!" << endl; return; } infile >> huffmancode; cout << huffmancode << endl;}*/void Huffman :: savecode(char *file){ outdata.open(file); if (!outdata) { cout << "ERROR" << endl; } outdata << huffmancode;}void Huffman::HuffmanCoding(){ //huffman树的建立 if (number <= 1) return; int m = 2 * number - 1; //哈弗曼树所需节点数 huffmantree = new HTNode[m + 1]; //0号单元未使用 huffmancharslist p; p = l -> next; int i; for (i = 1; i <= number; ++i)//初始化 { huffmantree[i].weight = p -> weight; huffmantree[i].parent = 0; huffmantree[i].lchild = 0; huffmantree[i].rchild = 0; p = p -> next; } for (i = number + 1; i <= m; ++i) { huffmantree[i].weight = 0; huffmantree[i].parent = 0; huffmantree[i].lchild = 0; huffmantree[i].rchild = 0; } for (i = number + 1; i <= m; ++i)//建哈弗曼树 { int s1, s2; select(i - 1, s1, s2); huffmantree[s1].parent = huffmantree[s2].parent = i; huffmantree[i].lchild = s1; huffmantree[i].rchild = s2; huffmantree[i].weight = huffmantree[s1].weight + huffmantree[s2].weight; } p = l -> next; //从叶子到根节点逆向求每个字符的哈弗曼编码 char *cd = new char[number]; //分配求编码的工作空间(每个字符编码结果最长n-1再加上'/0') cd[number - 1] = '/0'; //编码结束符 for (i = 1; i <= number; ++i) //逐个字符求哈弗曼编码 { int start = number - 1; int c, f; for (c = i, f = huffmantree[i].parent; f != 0; c = f, f = huffmantree[f].parent)//从叶子到根逆向求编码 { if (huffmantree[f].lchild == c) //左孩子编码为0 cd[--start] = '0'; else //右孩子编码为1 cd[--start] = '1'; } char *a[i]; a[i] = (char *) malloc ((number - start) * sizeof(char)); strcpy(a[i], &cd[start]); p -> code = a[i]; cout << p -> code << endl; p = p -> next; } delete[] cd; //清除缓存}void Huffman::select(int n, int &s1, int &s2){ //选取n个元素中权值最小的两个元素 s1 = s2 = 0; for (int i = 1; i <= n; ++i) { if (huffmantree[i].parent != 0) continue; if (s1 == 0) s1 = i; else if (s2 == 0) { if (huffmantree[i].weight < huffmantree[s1].weight) { s2 = s1; s1 = i; } else s2 = i; } else { if (huffmantree[i].weight < huffmantree[s1].weight) { s2 = s1; s1 = i; } else if (huffmantree[i].weight < huffmantree[s2].weight) s2 = i; } }}void Huffman::PrintCharWeight(){ //输出各字符及其权值(检验时用) huffmancharslist p; p = l -> next; while (p) { switch (p -> ch) { case '/t': cout << "//t"; break; case '/n': cout << "//n"; break; default: cout << p -> ch; break; } cout << "——" << p -> weight << endl; p = p -> next; }}void Huffman :: printtext(){ //输出文本 cout << text << endl;}void Huffman :: printcode(){ //输出代码 for (int i = 0; i <= huffmancode.size(); i ++) { cout << huffmancode[i]; if ((i + 1) % 50 == 0) { //每输出50个编码换行 cout << endl; } }}void Huffman :: Encode(){ //编码 huffmancharslist p; for (int i = 0; i < text.size(); i ++) { p = l -> next; for (int j = 1; j <= number; j ++) { if (text[i] == p -> ch) { huffmancode += p -> code; } p = p -> next; } }}void Huffman :: Decode(){ //解码 text = ""; string temp; huffmancharslist p; for (int i = 0; i < huffmancode.size(); i ++) { temp += huffmancode[i]; p = l -> next; for (int j = 1; j <= number; j ++) { if (temp == p -> code) { text += p -> ch; temp = ""; } p = p -> next; } } cout << text << endl;//输出编码}void Huffman :: get_number(){ //输入字符数 cout << "输入字符个数:" << endl; cin >> number;}void Huffman :: get_weight(){ //输入字符及权值 huffmancharslist p, q; p = (huffmancharslist) malloc (sizeof(LNode)); l -> next = p; cout << "请输入字符和权值:" << endl; int i; for (i = 1; i < number; ++i) { cin.ignore(); //清除输入缓冲区 cin.get(p -> ch); //输入单个字符,可以是空白符 cin >> p -> weight; q = (huffmancharslist) malloc (sizeof(LNode)); p -> next = q; p = q; } if (i == number) { cin.ignore(); cin.get(p -> ch); cin >> p -> weight; p -> next = NULL; }}void Huffman :: countchars(){ //统计输入的字符及个字符权值 huffmancharslist p, q, temp; p = (huffmancharslist) malloc (sizeof(LNode)); l -> next = p; p -> next = NULL; p -> ch = text[0]; p -> weight = 1; number = 1; for (int i = 1; i != text.size(); ++i) { int j; p = l -> next; for (j = 1; j <= number; ++j) { if (text[i] == p -> ch) { p -> weight ++; break; } temp = p; p = p -> next; } if (j > number) { p = temp; ++number; q = (huffmancharslist) malloc (sizeof(LNode)); q -> ch = text[i]; q -> weight = 1; p -> next = q; q -> next = NULL; } }}
huffman.h
#include <iostream>#include <string>#include <string.h>#include <stdlib.h>#include <fstream>using namespace std;typedef struct //huffmantree{ unsigned int weight; unsigned int parent, lchild, rchild;}HTNode, *HuffmanTree;typedef struct LNode //字符链表结点{ char ch; unsigned int weight; char *code; struct LNode *next;}LNode, *huffmancharslist;class Huffman{ private: ifstream indata; //输入文件流 ofstream outdata; //输出文件流 string huffmancode, text; int number; //字符链表结点个数 HuffmanTree huffmantree; huffmancharslist l; //头节点 public: Huffman() { //初始化 l = (huffmancharslist) malloc (sizeof(LNode)); l -> next = NULL; } void savetext(char *file); void readtext(char *file); void readcode(char *file); void savecode(char *file); void countchars(); void HuffmanCoding(); void select(int n, int &s1, int &s2); void Encode(); void Decode(); void get_number(); void get_weight(); void printcode(); void treeprint(); void PrintCharWeight(); void CountCharsWeight(); void printtext(); //void ReadCodeFromFile(char *filename);};
main.cpp
#include "huffman3.h"int main(){ Huffman huffman; huffman.readtext("text.txt"); huffman.printtext(); cout << "请选择是否系统自己统计权值? 1.yes 2.no 3.exit" << endl; int chose2; cin >> chose2; while (chose2 == 1 || chose2 == 2) { switch (chose2) { case 1: huffman.countchars(); break; case 2: huffman.get_number(); huffman.get_weight(); break; } cout << "建哈夫曼树……" << endl; huffman.HuffmanCoding(); cout << "编码中……" << endl; huffman.Encode(); cout << "保存编码……" << endl; huffman.savecode("code.txt"); cout << "输出编码结果:"; huffman.printcode(); cout << endl; cout << "从文件中读取编码……" << endl; huffman.readcode("code.txt"); //huffman.ReadCodeFromFile("code.txt"); cout << "解码……" << endl; huffman.Decode(); chose2 = 3; } while (chose2 != 1 && chose2 != 2 && chose2 != 3) { cout << "don't so stupid! just fallow my rules!" << endl; } return 0;}
0 0
- C++ 实现Huffman编译码器
- 数据结构实习Huffman编译码器(二)
- 数据结构实习之Huffman编译码器(一)
- 数据结构实习之Huffman编译码器(三)
- huffman编解码实现(C语言实现版本)
- Huffman哈夫曼编码译码器(文件输入输出流)C语言(C++)
- Huffman编码译码器 Android版本
- Huffman编解码实现文本压缩
- C++实现Huffman的编解码
- Huffman编码C实现
- Hamming(7,4)编译码器
- 【c++】Huffman实现文件压缩
- 【C++】Huffman树的实现
- Huffman 编解码算法实现与压缩效率分析
- Huffman树与Huffman编码(C语言实现)
- huffman编解码源代码
- 【数据压缩】Huffman编解码
- Huffman编解码
- 括号配对问题
- Http之Get/Post请求区别
- Building Your First App
- Spring中的AOP配置
- 斐波那契额数列
- C++ 实现Huffman编译码器
- IOS 关键字self,super,copy, retain, assign , readonly , readwrite, nonatomic、@synthesize、@property、@dyna
- mysql输入中文乱码怎么解决
- uva 147 - Dollars 钱币兑换问题(浮点数) 精度问题 完全背包
- 关于子类对象生成的问题(抽空展开写一下)
- 简单演示对象间通过BLOCK回调修改属性的功能
- 【Html】CSS注释代码
- 剑指offer系列之十四:反转链表
- activity_main.xml不能预览问题