赞
踩
用类与对象C++编程
分为头文件Huffman.h
和主函数main.cpp两部分
(功能陆续添加)
类的声明:
- class Huffman
- {
- private:
- HNode*HTree;//哈夫曼树节点
- HCode*HCodeTable;//存储编码表
- int N;//叶子节点数量
- void code(int i, string newcode);//递归函数,对第i个节点编码
- public:
- Huffman() {
- HTree = new HNode; HCodeTable = new HCode; N = 0;
- };
- void CreateHTree(int a[], int n, char name[]);//构建哈夫曼树
- void CreateCodeTable();//创建编码表
- void Encode(string s, char *d);//编码
- void Decode(char *s, char *d);//解码
- ~Huffman();//析构函数
- void SelectMin(int &x, int &y, int a, int b);//辅助搜索最小值函数
- void Printeach(int retime);//打印每一个字母对应的编码
- };//类的定义
两种结点的定义:
树中结点和编码中的结点:
- struct HNode
- {
- int weight;//结点权值
- int parent;//双亲数组下标
- int LChild;//左孩子数组下标
- int RChild;//右孩子数组下标
- };//每个结点的结构体
-
- struct HCode
- {
- char data;//存储节点的内存
- string code;//存储结点对应的编码
- };//记录每个节点的编码
具体代码如下:
Huffman.h
- #include<iostream>
- #include<algorithm>
- using namespace std;
- #define manum 0x3f3f3f3f
- struct HNode
- {
- int weight;//结点权值
- int parent;//双亲数组下标
- int LChild;//左孩子数组下标
- int RChild;//右孩子数组下标
- };//每个结点的结构体
-
- struct HCode
- {
- char data;//存储节点的内存
- string code;//存储结点对应的编码
- };//记录每个节点的编码
-
- class Huffman
- {
- private:
- HNode*HTree;//哈夫曼树节点
- HCode*HCodeTable;//存储编码表
- int N;//叶子节点数量
- void code(int i, string newcode);//递归函数,对第i个节点编码
- public:
- Huffman() {
- HTree = new HNode; HCodeTable = new HCode; N = 0;
- };
- void CreateHTree(int a[], int n, char name[]);//构建哈夫曼树
- void CreateCodeTable();//创建编码表
- void Encode(string s, char *d,int &contro);//编码
- void Decode(char *s, char *d);//解码
- ~Huffman();//析构函数
- void SelectMin(int &x, int &y, int a, int b);//辅助搜索最小值函数
- void Printeach(int retime);//打印每一个字母对应的编码
- };//类的定义
-
-
- /****************************类的成员函数的实现*/
- //辅助函数,搜索数列中最小的两个结点值
-
- void Huffman::SelectMin(int &x, int &y, int a, int b)
- {
- //cout << a << " " << b << endl;
- //cout << HTree[b - 1].weight << endl;
- int m = manum, n = manum;//最小的两个数
- for (int i = a; i < b; i++)
- {
- if (HTree[i].weight < m)
- {
- m = HTree[i].weight;
- x = i;
- }
- }
- for (int i = a; i < b; i++)
- {
- if (HTree[i].weight < n&&i!=x)
- {
- n = HTree[i].weight;
- y = i;
- }
- }
- }
-
-
- //构造哈夫曼树
- //a[]存储每种字符的权值,n为字符的种类,name为各个字符的内容
- void Huffman::CreateHTree(int a[], int n, char name[])
- {
- N = n;
- HCodeTable = new HCode[N];
- HTree = new HNode[2 * N - 1];//2*n-1为总结点个数
- for (int i = 0; i < N; i++)
- {
- HTree[i].weight = a[i];
- HTree[i].LChild = HTree[i].RChild = HTree[i].parent = -1;
- HCodeTable[i].data = name[i];
- }
- int x, y;
- for (int i = n; i < 2 * N - 1; i++)//开始构建哈夫曼树
- {
- SelectMin(x, y, 0, i);//从1~i中选出两个权值最小的结点
- //cout << "x=" << x <<" "<<HTree[x].weight<<endl;
- //cout << "y=" << y <<" "<<HTree[y].weight<<endl;
- HTree[x].parent = HTree[y].parent = i;
- HTree[i].weight = HTree[x].weight + HTree[y].weight;
- HTree[i].LChild = x;
- HTree[i].RChild = y;
- HTree[i].parent = -1;
- HTree[x].weight = HTree[y].weight = manum;
- }
- }
-
-
- //生成哈夫曼对应编码
- void Huffman::code(int i, string newcode)
- {
- if (HTree[i].LChild == -1)
- {
- HCodeTable[i].code = newcode;
- return;
- }
- code(HTree[i].LChild, newcode + '0');
- code(HTree[i].RChild, newcode + '1');
- }
- void Huffman::CreateCodeTable()//生成编码表
- {
- code(2 * N - 2, "");
- }
-
-
- //进行编码
- void Huffman::Encode(string s, char *d,int &contro)
- {
- contro = 0;
- int n2 = 0;//控制s的变量
- while (s[n2] != '\0')
- {
- for (int i = 0; i < N; i++)
- {
- if (HCodeTable[i].data == s[n2])
- {
- int k = 0;
- while (HCodeTable[i].code[k] != '\0')
- k++;//统计此字符对应编码的长度
- for (int j = 0; j < k; j++)
- {
- *d = HCodeTable[i].code[j];
- d++;
- contro++;
- }
- }
- }
- n2++;
- }
- }
-
- //进行解码
- void Huffman::Decode(char *s, char *d)
- {
- while (*s != '\0')
- {
- int parent = 2 * N - 2;//根结点在HTree的下标(有改动,原书中为2*n-2)
- while (HTree[parent].LChild != -1)//如果叶子结点不是根结点
- {
- if (*s == '0')
- parent = HTree[parent].LChild;
- else
- parent = HTree[parent].RChild;
- s++;
- }
- *d = HCodeTable[parent].data;
- d++;
- }
- }
-
-
- //打印函数,打印每一个字符的编码
- void Huffman::Printeach(int retime)
- {
- cout << "每一个字符对应的编码如下:" << endl;
- for (int i = 0; i < retime; i++)
- {
- cout << "i=" << i << " " << HCodeTable[i].data << " " << HCodeTable[i].code << endl;
- }
- }
-
-
- //析构函数
- Huffman::~Huffman()
- {
- N = 0;
- HTree = NULL;
- HCodeTable = NULL;
- }
-
- //5.16更新,修改vs上出现字符错乱的bug
-
-
-
main.cpp
- #include<iostream>
- #include<cstring>
- #include<string>
- #include"Huffman.h"
- using namespace std;
- #define Size 100
- string str;
- char name[60];//字符类型(0-25为大写,30-55为小写,26为下划线)
- int Time[60];//字符的权值
- char name2[60];
- int Time2[60];
- int main()
- {
- cout << "请输入你想传递的字符串(空格用下划线代替),如想结束程序,请输入(END)" << endl;
- while (cin >> str)
- {
- if (str == "END")
- break;
- memset(Time, 0, sizeof(Time));
- memset(Time2, 0, sizeof(Time2));
- int len = str.size();
- if (len > Size)
- {
- cout << "数据量超过可处理范围" << endl;
- cout << "请输入你想传递的字符串(空格用下划线代替),如想结束程序,请输入(END)" << endl;
- continue;
- }
- for (int i = 0; i < len; i++)
- {
- if (str[i] == '_')
- {
- Time[26]++;
- name[26] = '_';
- }
- if (str[i] >= 'A'&&str[i] <= 'Z')
- {
- Time[str[i] - 'A']++;
- name[str[i] - 'A'] = str[i];
- }
- if (str[i] >= 'a'&&str[i] <= 'z')
- {
-
- Time[str[i] - 'a' + 30]++;
- name[str[i] - 'a' + 30] = str[i];
-
- }
- }//录入并处理字符串
- int retime = 0;//实际上出现的字符个数
- for (int i = 0; i < 60; i++)
- {
- if (Time[i] != 0)
- {
- name2[retime] = name[i];
- Time2[retime] = Time[i];
- retime++;
- }
- }
- //cout << "retime=" << retime << endl;
- name2[retime] = '\0';
- //精细化两个数组
- //运用类完成功能
- Huffman Huf;
- //cout << retime << endl;
- Huf.CreateHTree(Time2, retime, name2);
- Huf.CreateCodeTable(); //树和表的建立
- Huf.Printeach(retime);//打印每一个字符对应的哈夫曼编码
- char *ar = new char[Size];//编码后的字符串
- char *br = new char[Size];//解码后的字符串
- int contro=0;
- Huf.Encode(str, ar,contro);
- cout << "编码结果如下:" << endl;
- for (int i = 0; i < contro; i++)
- cout << *(ar + i);
- cout << endl;
- //cout << ar << endl;
- cout << "解码结果如下:" << endl;
- Huf.Decode(ar, br);
- for (int i = 0; i < len; i++)
- cout << *(br + i) ;
- cout << endl;
- cout << "定长编码需要的长度是:" << len*5 << ";" << "哈夫曼编码的长度是:" << contro << endl;
- cout << "原编码是新编码的" << len * 5 * 1.0 / contro <<"倍"<< endl;
- Huf.~Huffman();
- cout << endl;
- cout << "请输入你想传递的字符串(空格用下划线代替),如想结束程序,请输入(END)" << endl;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。