数据结构课程设计-12月29日

时间:2022-09-02 14:30:33

今天来说课设依旧处于没有进展的状态,自己也处于游离状态。早上和班长在一起的时间还算是比较有趣的。

早上对昨天的代码进行改进,然并卵。自己没有掌握就是没有掌握,没有得到这个那个能力就是没有得到。早上后半程也就放弃了。

下午就在网上找代码,然后自己修改了下。//原代码见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);
 }
}



 
 

 

然后上面这个现在唯一的问题就是:

文本文件里面字符的统计,权值问题。

其它我感觉已经没有问题了。

感觉自己真的路选的......

就这样吧