课设是早上8点到中午1点,今天是第一天,比起上学期的课设,这次真的是比较从容淡定。
然而即使这样说,问题还是有的。
首先是对昨天晚上的前期设计做了些改变。
然后因为好久没写C,结果搞的有些都忘,文件操作那块也忘。
最后就是哈夫曼树并没有学习了解掌握,结果就是把老师课件上的代码copy过来。
以下先是今天的成果
#include<stdio.h>
#include<stdlib.h>
#define Max 1024
#define n 30
#define m 2*n-1
#define MAXINT 32767
typedef struct{
int weight;
int parent,Lchild,Rchild;
}HTNode,HuffmanTree[m];
int read(char x[]); //文件读取
int write(char x[]); //文件写入
void print(char x[]); //打印文件内容
void countChar(char x[]); //统计字符频度,权值放在一个数组中
void CrtHuffmanTree(HuffmanTree ht,int w[ ],int n); //哈弗曼树的建立
void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n); //哈弗曼树的编码
void CrtHuffmanTran(HuffmanTree ht,int n); //哈弗曼树的译码
char souce[Max]; //原文件内容的字符数组存放
char code[Max]; //编码后的字符数组存放
char decode[Max]; //译码后的字符数组存放
int length=0;
typedef struct{ //权值的存放
int l;
int x;
}charrr[Max];
charrr[0]={0,0};
typedef char *HuffmanCode[N+1] //指针数组动态存放每个编码串的头指针
int main(){
}
int read()
{
FILE *fp=fopen("x.souce","r"); //原文本本件名字x;
char c;
int i=0;
if (fp==NULL)
{
printf("Open failed...\n");
return 0;
}
while ((c=getc(fp))!=EOF)
{
souce[i]=c;
i++;
} //把读取的数据内容放到souce[]数组中
fp.close();
return 1;
}
void write(char name[],char x[]) //写入一个新的文件
{
FILE *fp=fopen(name,"w");
if (fp==NULL)
{
printf("Open failed...\n");
return 0;
}
fwrite(x,sizeof(char),sizeof(x),fp);
fclose(fp);
}
void print(char x[]){
int i=0;
while (x[i]!='\0') i++;
for (int j=0;j<i;j++)
printf("%s",x);
printf("\n");
}
void countChar(char x[]){
int i=0,j;
while (x[i]!='\0') i++;
char c;
if (read()) //读取原文件文件,用遍历统计字符频度算法souce;
{
for (j=0;j<=i;j++)
{
charrr[souce[j]].id=souce[j];
charrr[souce[j]].x++;
length++;
}
}
//权值放在一个数组中,然而现在权值让在了charrr[].x中
}
void sort(int x[])
{
int i,j;
int temp;
int min,minm;
for (i=0;i<N;i++)
for (j=i+1;j<N;J++)
if (x[i]>x[j])
{
temp=x[i];
x[i]=x[j];
x[j]=temp;
}
min=x[0];
minm=x[1];
}
void CrtHuffmanTree(HuffmanTree ht,int w[ ],int n){
countChar(); //获取个字符出现的频度,已放入quan[N];
n=length;
for (int i=0;i<n;i++) w[i]=charrr[i].x;
int i, s1 , s2, m;
m=2*n-1;
for(i=1;i<=n;i++)
{
ht[i].weight=w[i];
ht[i].parent=0;
ht[i].lchild=0;
ht[i].rchild=0;
}
for(i=n+1;i<=m;i++)
{
ht[i].weight=0;
ht[i].parent=0;
ht[i].lchild=0;
ht[i].rchild=0;
}
for(i=n+1;i<=m;i++)
{
select(ht,i-1,&s1,&s2);
ht[i].weight=ht[s1].weight+ht[s2].weight;
ht[s1].parent=i;
ht[s2].parent=i;
ht[i].lchild=s1;
ht[i].rchild=s2;
}
CrtHuffmanCode();
write(); //并将code内容写入新的*.code文件中
}
void select(HuffmanTree ht, int pos, int *s1, int *s2 ) //Huffman算法实现—选择函数
{
int i, j, m1,m2; /*m1存放最小权值,s1是m1在数组的下标*/
m1=m2=MAXINT; /*m2存放次小权值,s2是m2在数组的下标*/
for(j=1;j<=pos;j++)
{
if (ht[j].weight<m1 && ht[j].parent==0)
{ m2 = m1;
*s2=*s1;
*s1=j;
m1 = ht[j].weight;
}
else if(ht[j].weight<m2 && ht[j].parent==0)
{ m2 = ht[j].weight;
*s2 = j;
}
}
if(*s1>*s2)
/*使s1小于s2*/ { i=*s1; *s1=*s2; *s2=i; }
}
void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n) //哈弗曼树编码算法
{
char *cd;
int start,c,p,i;
cd=(char *)malloc(n*sizeof(char));
cd[n-1]='\0';
for(i=1;i<=n;i++) {
start=n-1;
c=i;
p=ht[i].parent;
while(p!=0) {
--start;
if(ht[p].lchild==c)
cd[start]='0';
else
cd[start]='1';
c=p;
p=ht[p].parent;
}
hc[i]=(char *)malloc((n-start)*sizeof(char));
strcpy(hc[i],&cd[start]);
}
free(cd);
for (int j=0;j<i;j++)
code[j]=hc[j]; //得hc[]后将编码内容放入code[];
}
void CrtHuffmanTran(HuffmanTree ht,char Code[],int n)//对code[]进行译码 //将译码结果放入decode[1024];//并将decode内容写入新的*.decode文件中
{
write();
}
然后,快要断电了,因为和班长讨论概率论问题
明天再总结一天。