今天来说课设依旧处于没有进展的状态,自己也处于游离状态。早上和班长在一起的时间还算是比较有趣的。
早上对昨天的代码进行改进,然并卵。自己没有掌握就是没有掌握,没有得到这个那个能力就是没有得到。早上后半程也就放弃了。
下午就在网上找代码,然后自己修改了下。//原代码见http://blog.163.com/panzhaoyang_sun@126/blog/static/2129538120103189230221/ 转自这个
//调用有文件以及定义常数值 #include "stdio.h" #include "string.h" #include "ctype.h" #define MAXLEN 100 #define MAXLEN_1 1000 //自定义类型声明 typedef struct { int weight; char data; int lchild,rchild,parent; }HFMTnode; typedef HFMTnode HFMT[MAXLEN]; typedef struct { char code[MAXLEN]; char data; }HFMCnode; typedef HFMCnode HFMC[MAXLEN]; typedef struct { char data[MAXLEN]; int top; }seqstack; typedef struct { char ch; int time; }count; count c[MAXLEN]={0,0}; //文件全局变量外部声明 extern int n; //多少个字符 extern int t=0; //多少个权值 //所有子函数声明 void InitializeTree(HFMT T); void countChar(); void InputTree(HFMT T); void Selectleast(HFMT T,int *p1,int *p2); void CreateHFMT(HFMT T); void push(char x); void hfmc(HFMT T,int i); void CreateHFMC(HFMT T,HFMC C); void Initialization(HFMT T,HFMC C); void Codeing(HFMC C); void Decodeing(HFMC C); void Showcodefile(); void Showdecodefile(); seqstack s; int main() { HFMT t; HFMC c; InitializeTree(t); CreateHFMT(t); CreateHFMC(t,c); Initialization(t,c); Codeing(c); Decodeing(c); return 0; } //初始化树 void InitializeTree(HFMT T) { int i; /* 把这块改成读取文件字符内容,然后初始化树 */ FILE *fp; fp=fopen("Data.txt","r"); if (fp==NULL) { printf("Open failed...\n"); } fseek(fp,0,SEEK_END); n=ftell(fp); for(i=0;i<2*n-1;i++) { T->weight=-1; T->lchild=-1; T->rchild=-1; T->parent=-1; T->data='\0'; } } void countChar(){ char now[1024]; char s; int i=0; int k=0; FILE *fp; fp=fopen("Data.txt","r"); if (fp==NULL) printf("Open failed...\n"); while((s=getc(fp))!=EOF) { now[i]=s; i++; } for (int j=0;j<=i;j++) { if (isalpha(now[j])) //a[tolower(c)-'a']++; { c[tolower(now[j])-'a']->ch=now[j]; c[tolower(now[j])-'a']->time++; } } //权值放在一个数组中,然而现在权值放在了charrr[].x中 while (c[k]->ch!=0) { t++; //权值数量 k++; } } void InputTree(HFMT T) { int i; for(i=0;i<t;i++) { /* printf("请输入第%d个字符与权重:",i+1); getchar(); scanf("%c %d",&T.data,&T.weight);*/ T->data=c[i]->ch; T->weight=c[i]->time; } } //从树数组中选取权值最小的两个元素 void Selectleast(HFMT T,int *p1,int *p2) { long min1,min2; int i; min1=min2=999999; for(i=0;i<2*n-1;i++) { if(T->parent==-1&&T->weight!=-1) if(T->weight<min1) { min1=T->weight; *p1=i; } } for(i=0;i<2*n-1;i++) { if(T->parent==-1&&T->weight!=-1) if(T->weight<min2&&i!=*p1) { min2=T->weight; *p2=i; } } } //构建哈夫曼树 void CreateHFMT(HFMT T) { int i,p1,p2; InitializeTree(T); InputTree(T); for(i=n;i<2*n-1;i++) { Selectleast(T,&p1,&p2); T->weight=T[p1]->weight+T[p2]->weight; T->lchild=p1; T->rchild=p2; T[p1]->parent=T[p2]->parent=i; } } //入栈 void push(char x) { s->top++; s->data[s->top]=x; } //构建哈夫曼树编码库递归调用函数 void hfmc(HFMT T,int i) { int j; j=T->parent; if(j!=-1) { if(i==T[j]->lchild) push('0'); if(i==T[j]->rchild) push('1'); hfmc(T,j); } } //构建哈夫曼树编码库 void CreateHFMC(HFMT T,HFMC C) { int i,j; s->top=-1; for(i=0;i<n;i++) { hfmc(T,i); C->data=T->data; for(j=0;s->top!=-1;j++) { C->code[j]=s->data[s->top]; s->top--; } C->code[j]='\0'; } } //初始化函数 void Initialization(HFMT T,HFMC C) { FILE *out; int i; CreateHFMT(T); CreateHFMC(T,C); if((out=fopen("Data.txt","w"))!=NULL) { fprintf(out,"%d",n); for(i=0;i<n;i++) fprintf(out,"%c",T->data); for(i=0;i<2*n-1;i++) fprintf(out,"\n%d %d %d %d",T->weight,T->parent,T->lchild,T->rchild); } else { printf("\n文件打开错误!"); return; } fclose(out); printf("\n初始化完毕!"); } //编码函数 void Codeing(HFMC C) { FILE *in,*out; char zw[MAXLEN],code[MAXLEN_1]; int i=0,j,k,c_len,error=1; c_len=0;//编码正文初始长度置零 //打开文件Data.txt并读取正文存入正文数组zw if((in=fopen("Data.txt","r"))!=NULL) { zw=fgetc(in); while(feof(in)==0) { i++; zw=fgetc(in); } zw='\0'; } else { printf("\n文件打开错误!"); return; } fclose(in); //进行编码 for(i=0;zw!='\0';i++) { error=1;//错误置为真 for(j=0;j<n;j++) { if(zw==C[j]->data) { for(k=0;C[j]->code[k]!='\0';k++) { code[c_len]=C[j]->code[k]; c_len++; } error=0;//若编码库存在匹配字符,则错误为假 break; } } if(error==1) break; } code[c_len]='\0'; if(error) { printf("\n编码错误,请重新检查!"); return; } else {//打开文件code.txt,并将编码正文写入文件 if((out=fopen("code.txt","w"))!=NULL) fprintf(out,"%s",code); else { printf("\n打开文件错误!"); return; } fclose(out); } } //译码函数 void Decodeing(HFMC C) { FILE *in,*out; int i,j,k,c_max,c_len,dq,dq_len,flag,error=0;//error初始状态为假 char code[MAXLEN_1],a[MAXLEN],zw[MAXLEN]; code[0]='\0'; //打开文件code.txt,读取编码正文写入内存,存入数组code if((in=fopen("code.txt","r"))!=NULL) { fscanf(in,"%s",code); } else { printf("\n打开文件错误!"); return; } fclose(in); //求编码正文长度c_len for(i=0;code!='\0';i++); c_len=i; if(c_len==0) error=1;//错误情况1 //求编码库最长编码长度c_max c_max=0; for(i=0;i<n;i++) { for(j=0;C.code[j]!='\0';j++); if(c_max<j) c_max=j; } //进行译码 dq=0; //dq用来记录code数组的读取位置 k=0; //k用来记录zw数组读取位置 while(dq<c_len) { flag=1; dq_len=c_max; for(i=dq,j=0;j<c_max;i++,j++) a[j]=code; a[j]='\0'; while(flag&&!error)//若无错误且flag为1则继续循环 { for(i=0;i<n;i++) { if(strcmp(a,C->code)==0) { zw[k]=C->data; k++; flag=0; break; } }//若找到编码库里匹配的编码,则结束循环 if(flag) { dq_len--; a[dq_len]='\0'; }//未找到则将当前长度减一,继续寻找 if(dq_len<1) error=1;//译码错误情况2 } dq=dq+dq_len;//编码正文当前读取位置改变 } zw[k]='\0';//在zw数组的最后一个位置添加字符串结束符 if(error) { printf("\n译码错误,请重新检查!"); return; } else { //打开文件textfile.txt,将译码正文即数组zw写入文件 if((out=fopen("decode.txt","w"))!=NULL) fprintf(out,"%s",zw); else { printf("\n打开文件错误!"); return; } fclose(out); } } //显示编码文件内容函数 void Showcodefile() { FILE *in; char code[MAXLEN_1]; int i; code[0]='\0'; //打开文件 if((in=fopen("code.txt","r"))!=NULL) { fscanf(in,"%s",code); } else { printf("\n打开文件错误!"); return; } fclose(in); //打印内容 printf("\n代码文件内容为:"); for(i=0;code!='\0';i++) { if(i%50==0) printf("\n"); printf("%c",code); } } void Showdecodefile() { FILE *in; char code[MAXLEN_1]; int i; code[0]='\0'; //打开文件 if((in=fopen("decode.txt","r"))!=NULL) { fscanf(in,"%s",code); } else { printf("\n打开文件错误!"); return; } fclose(in); //打印内容 printf("\n代码文件内容为:"); for(i=0;code!='\0';i++) { if(i%50==0) printf("\n"); printf("%c",code); } }
然后上面这个现在唯一的问题就是:
文本文件里面字符的统计,权值问题。
其它我感觉已经没有问题了。
感觉自己真的路选的......
就这样吧