分享
 
 
 

Huffman编码(数据结构--未完成代码)

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

#include <iostream.h>

#include <fstream.h>

#include <string.h>

class Data {

public:

char ch;

Data(){

ch = NULL;

}

};

typedef class Huffman {

public:

Data data;

int weight;

int parent, lchild, rchild;

Huffman(){

weight = parent = lchild = rchild = NULL;

}

} * HuffmanTree;

typedef char ** HuffmanCode;

// 在数组中选择两个小的权的数据

void Select(int *tw, int n, int &s1, int &s2)

{

// 建立临时变量temp_w,用来存放最小的weight

int temp_w, i = 1;

while(!tw[i])

{

i++;

}

temp_w = tw[i];

s1 = i;

// 第一遍先确定s1

for(; i<=n; i++)

{

if(temp_w > tw[i])

{

if(tw[i] != NULL)

{

temp_w = tw[i];

s1 = i;

}// ifin

}// if

}//for

i = 1;

while(!tw[i] || i == s1)

{

i++;

}

temp_w = tw[i];

s2 = i;

for(; i<=n; i++)

{

if(i == s1)

goto loop;

if(temp_w > tw[i])

{

if(tw[i])

{

temp_w = tw[i];

s2 = i;

}// ifin

loop:;

}// if

}// for

// 使权小的放到s1

if(tw[s1]>tw[s2])

{

temp_w = s1;

s1 = s2;

s2 = temp_w;

}// if

// 取得两个小的位置后,将备用temp_array_w位置上的权抹去,表示已经被访问

tw[s1] = tw[s2] = NULL;

tw[0] = tw[0]-2;

}

void Initialization (HuffmanTree &HT, HuffmanCode &HC, int n)

{

// 给文件一编码个数的个标记,放在HT[0]行中

HT[0].weight = n;

HT[0].data.ch = 3;

int i;

// 建立一个辅助建立树用的权组

int *temp_array_w = new int[2*n];

// 初始化数组里的权都为0

for(i = 1; i<=2*n -1; i++)

temp_array_w[i] = 0;

for(i = 1; i<=n; i++)

{

cout << "输入字符: ";

cin >> HT[i].data.ch;

if(HT[i].data.ch == '\32')

HT[i].data.ch = '|';

cout << "输入权: ";

cin >> HT[i].weight;

// 把辅助权组赋和权一样的值

temp_array_w[i] = HT[i].weight;

// 用不用的0号单元记录个数

temp_array_w[0] = i;

}// for

// 建立标志s1和s2

int s1, s2;

s1 = s2 = NULL;

// 建立huffman树

for(i = n + 1; i<=2*n - 1; i++)

{

Select(temp_array_w, i-1, s1, s2);

cout << s1 << "//" << s2 << endl;

HT[i].weight = temp_array_w[i] = HT[s1].weight + HT[s2].weight;

HT[i].lchild = s1;

HT[i].rchild = s2;

HT[s1].parent = HT[s2].parent = i;

HT[i].data.ch = '#';

}// for

cout << "\tData\tweight\tparent\tlchild\trchild" << endl;

for(i = 1; i<=2*n - 1; i++)

cout << "\t" << HT[i].data.ch << "\t" << HT[i].weight << "\t" << HT[i].parent << "\t" << HT[i].lchild << "\t" << HT[i].rchild << endl;

// 建立好了树后打印输出到文件humTree中

ofstream HumTreeOut("humTree.dll");

// 把个数记录到文件开始

HumTreeOut << HT[0].weight << endl;

for(i = 1; i<=2*n -1; i++)

{

HumTreeOut << HT[i].data.ch << "\n" << HT[i].weight << "\n" << HT[i].parent << "\n" << HT[i].lchild << "\n" << HT[i].rchild << endl;

}

HumTreeOut.close();

}// void

// 通过树给字符编码,并且把编码输入到CodeFile中

void Encoding (HuffmanCode &HC, HuffmanTree &HT, int n, ifstream &tobetranfile)

{

char *cd = new char[n];

cd[n-1] = '\0';

int i = 1;

for(; i<=n; i++)

{

int start = n -1;

int c, f;

for(c = i, f = HT[i].parent; f!=0; c = f, f = HT[f].parent)

if(HT[f].lchild == c)

cd[--start] = '0';

else

cd[--start] = '1';

HC[i] = new char[n-start];

strcpy(HC[i], &cd[start]);

}

delete cd;

char temp_file_ch;

ofstream CodeOut("CodeFile.txt", ios::ate); // ios::ate表示一个open模式,是在文件后面续写

while(!tobetranfile.eof()) // 一旦文件到了末尾,eof()函数会返回一个非零值

{

tobetranfile.get(temp_file_ch);

for(i = 1; i<=n; i++)

{

if(temp_file_ch == HT[i].data.ch) // 如果相等,便用编码替换

CodeOut << HC[i];

}

}

CodeOut.close();

}

void Decoding (HuffmanTree &HT, ifstream &CodeFile, int n)

{

ofstream TextOut("TextFile.txt", ios::ate);

char temp_code_ch;

int temp_num = 2*n - 1;

while(!CodeFile.eof())

{

CodeFile.get(temp_code_ch);

if(temp_code_ch == '1')

if(!HT[temp_num].rchild)

{

TextOut << HT[temp_num].data.ch;

temp_num = 2*n - 1;

}

else

{

temp_num = HT[temp_num].rchild;

if(!HT[temp_num].rchild) //其实随便一个孩子为空就代表是叶子节点

{

TextOut << HT[temp_num].data.ch;

temp_num = 2*n - 1;

}

}

else

if(!HT[temp_num].lchild)

{

TextOut << HT[temp_num].data.ch;

temp_num = 2*n - 1;

}

else

{

temp_num = HT[temp_num].lchild;

if(!HT[temp_num].lchild) //其实随便一个孩子为空就代表是叶子节点

{

TextOut << HT[temp_num].data.ch;

temp_num = 2*n - 1;

}

}

}

TextOut.close();

cout << "已经翻译到Text.txt文件中" << endl;

}

// 通过已存在的humtree.dll建立新的树

bool CreatNewHum(HuffmanTree &HT, int &n)

{

char *ch_name = new char[30];

// 存放从文件中读取的字符

int temp_n;

char temp_ch;

int i = 1;

cout << "Please Inputing the File name :";

cin >> ch_name;

ifstream HuffmanTreeIn(ch_name);

if(HuffmanTreeIn.fail())

{

HuffmanTreeIn.close();

cout << "不能打开文件" << endl;

return false;

}

// HuffmanTree HT_TEMP = HT;

// HuffmanTreeIn.getline(temp_line, 9);

HuffmanTreeIn >> temp_n; // 一个单词为单位输入

HuffmanTreeIn.get(temp_ch);

// HuffmanTreeIn.seekg(1);

HT = new Huffman[2*temp_n];

// delete HT_TEMP;

// 通过读入文件中的数据给HT赋值

/*

for(;i<20;i++)

{

HuffmanTreeIn.get(temp_ch);

cout << temp_ch;

}

//*/

//*

int j = 1;

while(!HuffmanTreeIn.eof())

{

if(i%5 == 1)

{

HuffmanTreeIn >> HT[j].data.ch;

HuffmanTreeIn.get(temp_ch); // 用于回收回车符号

i++;

}

if(i%5 == 2)

{

HuffmanTreeIn >> HT[j].weight;

HuffmanTreeIn.get(temp_ch);

i++;

}

if(i%5 == 3)

{

HuffmanTreeIn >> HT[j].parent;

HuffmanTreeIn.get(temp_ch);

i++;

}

if(i%5 == 4)

{

HuffmanTreeIn >> HT[j].lchild;

HuffmanTreeIn.get(temp_ch);

i++;

}

if(i%5 == 0)

{

HuffmanTreeIn >> HT[j].rchild;

HuffmanTreeIn.get(temp_ch);

i++;

}

// i自加到5的倍数后j++

if(i%5 == 1)

j++;

// 防止输入最后一个定位符号

if(i > (2*temp_n -1)*5)

break;

}// while

//*/

// 从指定文件里读入树型

HuffmanTreeIn.close();

n = temp_n;

return true;

}

void PrintCode ()

{

char *name_ch = new char[51];

ifstream FileIn("CodeFile.txt");

ofstream FileOut("CodePrin.txt", ios::ate);

if(FileIn.fail())

cout << "文件打开错误!" << endl;

while(!FileIn.eof())

{

FileIn.getline(name_ch, 51);

cout << name_ch << endl;

FileOut << name_ch << endl;

}

FileIn.close();

FileOut.close();

}

void TreePrint ()

{

}

void TitalPrinT() {

cout << "\t=========================================================" << endl;

cout << endl;

cout << "\t=\t\t\tHUFFMANTREE\t\t\t=" << endl;

cout << endl;

cout << "\t=\t\tI:INITIAL A HUFFMAN TREE\t\t=" << endl;

cout << endl;

cout << "\t=\t\tE:ENCODEING THE DATA\t\t\t=" << endl;

cout << endl;

cout << "\t=\t\tD:DECODEING THE DATA\t\t\t=" << endl;

cout << endl;

cout << "\t=\t\tQ:QUIT\t\t\t\t\t=" << endl;

cout << endl;

cout << "\t=========================================================" << endl;

}

// 把几个运算的函数全都放到一个里面去,主函数main就只调用下运算函数

void ComputeHuffman ()

{

// 建立个临时输入存放选项的变量

char temp_input = NULL;

TitalPrinT();

// 记录要给几个编码

int n = 0;

// 先是主体界面 直到按Q才退出

while(temp_input != 'Q')

{

// 建立操作变量

char temp_choise = 0;

HuffmanTree HT;

HuffmanCode HC;

// 用switch/case来判断到底按了哪个选项

cout << "CHOOSE WHICH DO YOU SELECT..." << endl;

cin >> temp_input;

switch(temp_input)

{

case 'I':

cout << "How many numbers need to be initialized: ";

cin >> n;

// 建立数组存放数据

HT = new Huffman[2*n];

Initialization (HT, HC, n);

break;

case 'E':

{

//*

cout << "Inputing the HumffmanTree from the (F)ile or (M)emory : ";

cin >> temp_choise;

switch(temp_choise)

{

case 'F':

if(!CreatNewHum(HT, n))

continue;

break;

case 'M':

// 什么都不做

break;

default:

cout << "Please Pess F or M..." << endl;

continue;

}// switch

//*/

cout << "Translating in (F)ile or (P)ressing: ";

cin >> temp_choise;

switch(temp_choise)

{

case 'F':

break;

case 'P':

{

cout << "由于本人精力限制,现在最多只能输入80个字符" << endl;

char *temp_press_word = new char[81];

cin >> temp_press_word;

// 可以覆盖以前的ToBeTran.txt文件

ofstream CodeFileOut("ToBeTran.txt");

CodeFileOut << temp_press_word;

break;

}

}

HC = new char*[n+1];

ifstream ToBeTranFile("ToBeTran.txt");

Encoding(HC, HT, n, ToBeTranFile);

ToBeTranFile.close();

for(int i = 1; i<=n; i++)

cout << HT[i].data.ch << "<-->" << HC[i] << endl;

}

// 利用建立好的huffman树(如果不在内存则从文件humTree中读入),对文件

// ToBeTran中的正文进行编码,然后将结果寸入CodeFile.txt文件中.

break;

case 'D':

{

// 可以通过不同的树来翻译

cout << "Inputing the HumffmanTree from the (F)ile or (M)emory : ";

cin >> temp_choise;

switch(temp_choise)

{

case 'F':

{

if(!CreatNewHum(HT, n))

continue;

HC = new char*[n+1];

/*

ifstream ToBeTranFile("ToBeTran.txt");

Encoding(HC, HT, n, ToBeTranFile);

ToBeTranFile.close();

*/

}

break;

case 'M':

// 什么都不做

break;

default:

cout << "Please Pess F or M..." << endl;

continue;

}// switch

ifstream CodeFile("CodeFile.txt");

Decoding(HT, CodeFile, n);

CodeFile.close();

}

// 利用建立好的haffman树将文件codefile中的代码进行翻译.结果寸入文件TextFile.txt中

break;

case 'P':

PrintCode();

// 打印代码,50个每行,并且将此字符形式的编码文件写入CodePrin中

break;

case 'T':

// 印huffman树,将已经在内存的huffman树以直观的方式显示,同时将此字符形式的huffman树写

// 入文件TreePrint中

break;

case 'Q':

return;

default:

cout << "Please inputing in \" I E D Q \"..." << endl;

continue;

}// switch

// 回到主菜单

TitalPrinT();

}// while

}// ComputerHuffman

void main()

{

ComputeHuffman();

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有