赞
踩
数据结构做到哈夫曼,找到了以前的代码
使用时:按1回车,输入字符串,回车,然后依次2,回车,3,回车…n,回车
#include <iostream> #include <cstring> #include <iomanip> // #include "Huffman.h" using namespace std; char s[150]; //目标字符串 char ch[150]; //出现过的字符 int num[150]; //ch中字符对应的个数 int position[150]; //直接下标为ASCll码存储字符在num及ch中的位置 char Encoded[1024]; //存放编码过后的字符串 char ans[1024]; //存放编码再解码的字符串 int m, n; //样例:I love data Structure, I love Computer. I will try my best to study data Structure. // struct HCode { char data; char code[100]; }; struct HNode { int weight; int Lchild, Rchild; int parent; }; class Huffman { private: int originalLen; int newLen; HNode* huffTree; HCode* HCodeTable; int N; public: void CreateHTree(int a[], int n); //建树 void CreateCodeTable(char b[], int n); //建码表 void Encode(char* s, char* d, int n, int a[]); //编码 void Decode(char* s, char* d, int n); //解码 void checkLen(); //输出编码前后长度 void PrintTree(char *s); //凹入法打印 void PreOrder(int root, int depth, char *s); //前序遍历 ~Huffman(); }; void SelectMin(HNode* hTree, int n, int& i1, int& i2); void Reverse(char c[]); void work() {//对字符串进行统计处理 cout << "正在对字符串进行处理" << endl; m = strlen(s), n = 0; int pos(0); for (int i = 0; i < m; i++) { if (position[s[i]]) { num[position[s[i]]] += 1; } else { position[s[i]] = ++pos; ch[pos] = s[i]; num[pos] = 1; } } n = pos; for (int i = 1; i <= n; i++) { cout << std::left << ch[i] << ":" << setw(8) << num[position[ch[i]]] << " "; if (i % 5 == 0) puts(""); } puts(""); } int main() { Huffman test; //************************************* int op(-1); cout << "0:停止进程" << endl; cout << "1:输入字串" << endl; cout << "2:建树" << endl; cout << "3:建表" << endl; cout << "4:编码" << endl; cout << "5:解码" << endl; cout << "6:查看长度" << endl; cout << "7:打印树" << endl;//凹入表示法 cout << "I love data Structure, I love Computer. I will try my best to study data Structure." << endl; cout << "------------------------*" << endl; //************************************* while (cin >> op) { if (!op) { cout << "进程停止" << endl; break; } if (op == 1) {//输入要进行操作的字符 cout << "输入要进行操作的字串:" << endl; getchar(); cin.getline(s, 150); cout << "------------------------*" << endl; work(); cout << "------------------------*" << endl; } if (op == 2) {//建树 cout << "---------TreeCreating" << endl; test.CreateHTree(num + 1, n); cout << "------------------------*" << endl; } if (op == 3) {//建表 test.CreateCodeTable(ch + 1, n); cout << "------------------------*" << endl; } if (op == 4) {//编码 test.Encode(s, Encoded, m, position); cout << "----------stringEncoded:" << endl << Encoded << endl; cout << "------------------------*" << endl; } if (op == 5) {//解码 test.Decode(Encoded, ans, n); cout << "----------stringDecoded:" << endl << ans << endl; cout << "------------------------*" << endl; } if (op == 6) {//查看压缩前后字串长度 test.checkLen(); cout << "------------------------*" << endl; } if (op == 7) { test.PrintTree(ch + 1); cout << "------------------------*" << endl; } } return 0; } void Huffman::CreateHTree(int a[], int n) { N = 2 * n - 1; huffTree = new HNode[2 * n - 1]; for (int i = 0; i < n; i++) { huffTree[i].weight = a[i]; huffTree[i].Lchild = -1; huffTree[i].Rchild = -1; huffTree[i].parent = -1; } int li, ri; for (int i = n; i < 2 * n - 1; i++) { SelectMin(huffTree, i, li, ri); huffTree[li].parent = huffTree[ri].parent = i; huffTree[i].weight = huffTree[li].weight + huffTree[ri].weight; huffTree[i].Lchild = li; huffTree[i].Rchild = ri; huffTree[i].parent = -1; } cout << "---------Tree Created" << endl; } //建表 void Huffman::CreateCodeTable(char b[], int n) { cout << "---------CodeTable Creating..." << endl; HCodeTable = new HCode[n]; for (int i = 0; i < n; i++) { HCodeTable[i].data = b[i]; int k = 0, ic = i; int ip = huffTree[i].parent; while (ip != -1) { if (ic == huffTree[ip].Lchild) HCodeTable[i].code[k] = '0'; else HCodeTable[i].code[k] = '1'; k++, ic = ip; ip = huffTree[ic].parent; } HCodeTable[i].code[k] = '\0'; Reverse(HCodeTable[i].code); } cout << "---------CodeTable Created..." << endl; //输出码表:如下 cout << "输出码表如下:" << endl; for (int i = 0; i < n; i++) { cout << std::left << b[i] << ":" << setw(12) << HCodeTable[i].code; if ((i+1) % 5 == 0) puts(""); } puts(""); } //编码 void Huffman::Encode(char* s, char* d, int n, int position[]) { originalLen = n; cout << "----------Encoding..." << endl; int pos = 0; for (int i = 0; i < n; i++) { int k = strlen(HCodeTable[position[s[i]] - 1].code); for (int j = 0; j < k; j++) d[pos++] = HCodeTable[position[s[i]] - 1].code[j]; } newLen = pos; } //解码 void Huffman::Decode(char* s, char* d, int n) { cout << "----------Decoding..." << endl; //cout << s << endl; while (*s != '\0') { int k = 2 * n - 2; while (huffTree[k].Lchild != -1) { if (*s == '0') k = huffTree[k].Lchild; else k = huffTree[k].Rchild; s++; } *d = HCodeTable[k].data; d++; } } Huffman::~Huffman() { delete [] huffTree; delete [] HCodeTable; } //倒置数组 void Reverse(char *c) { int k = strlen(c); int i = 0, j = k - 1; while (i < j) { swap(c[i], c[j]); i++, j--; } } //寻找最小的两个作为兄弟 void SelectMin(HNode* hTree, int n, int& i1, int& i2) { int i; for (i = 0; i < n; i++) if (hTree[i].parent == -1) { i1 = i; break; } for (++i; i < n; i++) if (hTree[i].parent == -1) { i2 = i; break; } if (hTree[i1].weight > hTree[i2].weight) swap(i1, i2); for (++i; i < n; i++) { if (hTree[i].parent == -1) { if (hTree[i].weight < hTree[i1].weight) i2 = i1, i1 = i; else if (hTree[i].weight < hTree[i2].weight) i2 = i; } } } void Huffman::checkLen() { cout << "编码前长度:" << originalLen << " byte" << endl; cout << "编码后长度:" << newLen << " bit (如果用bit编码)" << endl; } void Huffman::PreOrder(int root, int depth, char *s) { if (huffTree[root].weight) { for (int i = 0; i < depth*2; i++) cout << " "; cout << std::left << setw(25-depth * 2) << setfill('-') << huffTree[root].weight; if (huffTree[root].Lchild == -1 && huffTree[root].Rchild == -1) { cout << s[root]; if (s[root] == ' ') cout << "(空格)"; } cout << endl; } if (huffTree[root].Lchild != -1) PreOrder(huffTree[root].Lchild, depth + 1, s); if (huffTree[root].Rchild != -1) PreOrder(huffTree[root].Rchild, depth + 1, s); } void Huffman::PrintTree(char *s) { cout << "----------TreePrinting..." << endl; PreOrder(N-1, 1, s); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。