#include<iostream> #include<string> using namespace std; int ABC[104] = { 0 }; //每个字符 权重初始为0 前大后小 int n = 0; bool flag[104] = { false }; //已经处理过 初始false为未处理 char text[10000]; //用text数组将a.txt里面的内容存储 char txt[10000]; //尽可能的大 否则二进制编码越界 int haffman[52][50] = {-1}; FILE *p; int h = 0; //作为全局变量 作用于反编码过程 记录数组下标 struct node { int data; //仍然以数组的下标表示 字符abc int rchild = -1; //右子树 int lchild = -1; //左子树 }nodetree[103]; //寻找数组中最小的值 返回下标 int findmin() { int i = 0; int j = 0; int weight = 0; while (!flag[i]) i++; j = i; weight = ABC[i]; for (; i < 104; i++) { if (flag[i] == true && weight > ABC[i]) //找出字幕出现次数大于0 且最小的 { weight = ABC[i]; j = i; } } flag[j] = false; //找出的最小值下次不再参与 return j; } void creat() { for (int i = 0; i < 52+n-1; i++) { nodetree[i].data = i; } //cout << "最小值排序 :" << endl; for (int i = 52; i <52+n-1; i++) { int a = findmin(); int b = findmin(); //cout << a <<" "<< ABC[a] << endl << b <<" "<<ABC[b] << endl; //cout << char(a + 97-26) << endl; //cout << char(b + 97-26) << endl; nodetree[i].lchild = a; nodetree[i].rchild = b; ABC[i] = ABC[a] + ABC[b]; flag[i] = true; } cout << endl; //for (int i = 52; i < 52 + n - 1; i++) //{ // cout << nodetree[i].data << " " << nodetree[i].lchild << "," << nodetree[i].rchild << endl; //} } int asc[50]; //用以暂时存放haffman编码 int j = -1; //j不会变化 void visittree(node tree) { if (tree.lchild == -1 && tree.rchild == -1) //叶子节点储存字母 { int i = 0; if (tree.data < 26) cout << char(65 + tree.data) << "编码:"; else cout << char(tree.data + 97 - 26) << "编码:"; while (asc[i] != -1) { haffman[tree.data][i] = asc[i]; cout << asc[i++]; } cout << endl ; return; } j++; asc[j] = 0; visittree(nodetree[tree.lchild]); asc[j] = 1; visittree(nodetree[tree.rchild]); asc[j] = -1; j--; } //输入根节点与数组下标 返回数组下标 haffman反编码 int decode(node tree,int i) { if (tree.lchild == -1 && tree.rchild == -1) { if(tree.data<26) fprintf(p, "%c", tree.data +65); else fprintf(p, "%c", tree.data + 97 - 26); return h; } h++; if (text[i] == '0') decode(nodetree[tree.lchild],i+1); else decode(nodetree[tree.rchild],i+1); } int main() { //进行初始化 memset(flag, false, sizeof(flag)); memset(asc, -1, sizeof(asc)); memset(haffman, -1, sizeof(haffman)); //读取已存在的文件a.txt 并把文件内容放到text数组与txt数组中 方便操作 char ch; int i = 0; p = fopen("E:\a.txt", "r"); if (p == NULL) { printf("failed to open file. "); exit(1); } cout << "原文中含有的英文字母是:" << endl; while ((ch = getc(p)) != EOF) { if (ch >= 65 && ch <= 90||ch>=97&&ch<=122) { txt[i] = ch; text[i++] = ch; cout << ch; } } //text[i] = ' '; //txt[i] = ' '; fclose(p); //输出文件中a-z,A—Z的出现的次数 以及总共出现的字母数 cout << endl; i = 0; while (text[i] != '