您的位置:首页 > 移动开发 > 微信开发

成长路上的小程序之—— 哈夫曼编码、译码

2013-11-29 21:05 375 查看
这是大二数据结构第七次上机老师布置的任务:实现文件操作,对文件进行哈夫曼编码、译码

之所以为此写一篇博客,是因为自认为这个程序对我的意义比较重大。

我是以一个课程设计的要求来写的,大一结束的暑假也做了一个课程设计:《学生通讯录》

但是太水了,完全没有难度。

这个相对来说则有一些巧妙的思想,完全是我独立完成的!

哈哈哈

代码如下:

#include <cstdlib>
#include <iostream>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#include "huffmantree.h"
#define MAX 1000000
using namespace std;

char str[MAX],ch[20];
int  n=0;
FILE *fp1, *fp2;
HuffmanTree HT;
HuffmanCode HC;

int main(int argc, char *argv[])
{
void menu(void);
menu();
system("PAUSE");
return EXIT_SUCCESS;
}

void menu(void)//菜单
{
void encoded(void);//编码
void decoded(void);//译码
system("cls");
printf("\n\t\t**************编码译码菜单********\n\n");
printf("\n\t\t**************1、编码\n");
printf("\n\t\t**************2、译码\n");
printf("\n\t\t**************3、退出\n");
printf("\n\t\t**********************************\n\n");
printf("\n\n\t\t************请选择(1/2/3):\n\n");
char ch=getch();//不需要回车
switch(ch)
{
case '1': encoded();break;
case '2': decoded();break;
case '3': exit(0);
}

}

void encoded()
{
int w[30];
printf("\n\t\t******************编码过程如下:\n");
//编码
fp1 = fopen("in.txt", "r");
fp2 = fopen("out.txt", "w");
fgets(&str[1],MAX,fp1);
//文件读取完成 ,从1下标处开始读取,因为哈夫曼编码从1开始
//这里&str[1]个人觉得比较巧妙  ^_^
int len = strlen(&str[1]);//字符总个数
printf("\n\t\t******************字符总个数为 %d 个\n",len);
int count[30] = {0};
for(int i=1; i<=len; i++)
if(isalpha(str[i]))
{
str[i] = tolower(str[i]);//全部转换为小写字母
count[str[i]-'a'+1]++;//统计字符出现个数,简单明了,值得表扬 ^_^
}
for (int i=1; i<=26; i++)
if (count[i])
{
w[i] = count[i];//赋给哈夫曼中的权值
n++;//统计出现字母类别个数
}
HuffmanCoding(HT,HC,w,n);//调用哈夫曼

for(int i=1; i<len; i++)
{
if(isalpha(str[i]))
fputs(HC[str[i]-'a'+1],fp2);
else
fprintf(fp2,"%c",str[i]);
}
fclose(fp1);
fclose(fp2);
printf("\n\n\t\t编码成功!\n");
printf("\n\n\t\t编码结果保存在out.txt文件中");
printf("请查看文件! ");
system("pause");
menu();
}

void decoded()
{
void ncpy(char ch[],char* str,int index,FILE* fp,int* countc);
printf("\n\t\t******************译码过程如下:\n");
fp1=fopen("out.txt","r");
fp2=fopen("result.txt","w");
fgets(str,MAX,fp1);//取出编码结果
int index=2;
int len=strlen(str);
int countc=1;
for(int j=0; j<len; )
{
//这里我觉得是我代码中最值得称赞的地方
//从这里可以看到刷题的影子
ncpy(ch,&str[j],++index,fp2,&countc);
for(int i=1; i<=n; i++)
if(!strcmp(ch,HC[i]))
{
fprintf(fp2,"%c",'a'+i-1);
j+=index;
index=2;
//判别一个字符成功,继续判别下一个字符
//改变j的值,使从下一段01代码中复制
//重新赋值index=2;
countc=1;
}
}
fclose(fp1);
fclose(fp2);
printf("\n\t\t译码成功!\n");
printf("\n\t\t译码结果保存在result.txt文件中!\n");
printf("\n\t\t请查看! ");
system("pause");
menu();
}

void ncpy(char ch[],char* str,int index,FILE* fp,int* countc)
//自己写的复制字符串函数,舍掉了字符串中的符号
{
int k=0;
for(int i=0; i<index; i++)
if(str[i]=='1'||str[i]=='0')
ch[k++]=str[i];
else if(*countc)
{
fprintf(fp,"%c",str[i]);
*countc=0;
//这里是我完成程序前的最后一关
//用countc控制即使多次调用函数,也只输出一次符号
}
ch[k]='\0';
}


继续加油~!~!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: