自写项目——哈夫曼编译码及客户端服务端交互实现

1.项目要求


哈夫曼编译码

题目要求:编写一个用哈夫曼实现的编码压缩器,语言不限!

实现英文字符编译码的功能;实现译码的压缩解压功能;要有较美观的图形用户界面;从客户端发送一段字符给服务器端,服务器端能成功的返回这段字符经过哈夫曼编译码之后的结果!

编写步骤:

①编写较美观的图形用户界面;

     ②得到客户端所发送的字符信息,并进行统计,每个字符 的频度作为哈夫曼树叶子结点的权值,并构建哈夫曼树;

③进行哈夫曼树的编码和译码;

④自行选取5~7个二进制码来进行压缩;

⑤将压缩好的字符发送到服务器端,并接受;

⑥解压----译码-----编码-----还原成原来的字符!

 

2.项目实现

直接上代码(其中有详细注释,ubuntu 16.04 编译通过!):


clien.cpp


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define BUFFER_SIZE 1024


#define MaxValue 10000//权值最大值 
#define MaxBit 55//最大编码位数 
#define MaxN 55//最大结点个数 

//准备工作
int sockfd;//
char* IP = "127.0.0.1";//该地址请写测试服务器的IP,本机IP,回送地
short PORT = 10222;//端口号
typedef struct sockaddr SA;//类型转换
char message[100];
char demessge[100];






void init()
{
    printf("客户端开始启动\n");
    sockfd = socket(AF_INET,SOCK_STREAM,0);//启动socket
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = inet_addr(IP);
    if(connect(sockfd,(SA*)&addr,sizeof(addr))==-1){//向服务器请求建立链接
        perror("无法连接到服务器");
        printf("客户端启动失败\n");
        exit(-1);
    }
    printf("客户端启动成功\n");
}
//开始通信

void code(int * count)
{
    int t;
    printf("\nplease input message:");
    scanf("%s",message);
    send(sockfd,message,sizeof(message),0);// 把文件大小数据发送
    recv(sockfd,count,sizeof(int),0);//得到编码后的结果大小
    printf("\nthe result:\n");
    for(int i=0;i<*count;i++)
    {
        recv(sockfd,&t,sizeof(int),0);//一个一个接受,并输出
        if(t == 2) 
            printf(" ");
        else
            printf("%d",t);
    }  
    getchar();
    getchar();
}

void decode()
{
    char result[100];
    printf("\nplease input the message you want tanslate:");
    scanf("%s",demessge);//得到要译的码
    send(sockfd,demessge,sizeof(demessge),0);//发送到服务端
    recv(sockfd,result,sizeof(result),0);//从服务端接受到译码后的结果
    printf("\nthe result:\n");
    printf("%s",result);
    getchar();
    getchar();
}








void start()
{
    int count=0;
    char result[100];
    int choice=1;
    int judge;
   //菜单
    do{
        judge=1;
        printf("\n\t********************************************\n");
        printf("\t**            1.字符压缩                    **\n");
        printf("\t**            2.字符解压                    **\n");
        printf("\t**            0.退出                        **\n");
        printf("\t********************************************\n");
        printf("\t请选择:");
        scanf("%d",&choice);
        
        if(choice == 1||choice == 0||choice == 2)
            send(sockfd,&choice,sizeof(int),0);//发送用户选择信息
        else  
            continue;
        
        
        recv(sockfd,&judge,sizeof(int),0);//接受判断标准,判断其是否为错误
        


        if(judge==1) {//如果错误,提示先用1选项建树
            printf("there is no haffe tree! \nplease set up the tree first!\n");
            continue;
        }
        

        switch(choice)
        {
            case 1 :
                code(&count);//编码
                break;
            case 2 :
                decode();//译码
                break;
            default:
                break;
        }
    }while(choice != 0);



    close(sockfd);//关闭socket
}




void sig_close(int i)
{
    //关闭客户端的描述符
    close(sockfd);
    exit(0);
}


int main()
{
    int type;
    signal(SIGINT,sig_close);//关闭CTRL+C
    init();//启动并连接服务器
    start();//开始与服务器进行通信。
    return 0;
}


server.cpp


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define MaxValue 10000//权值最大值 
#define MaxBit 55//最大编码位数 
#define MaxN 55//最大结点个数 

char message[100];
//准备工作

int sockfd;//
char* IP = "127.0.0.1";//服务器IP
short PORT = 10222;//端口号
typedef struct sockaddr SA;//类型转换


/*====================================
=1.构造哈夫曼树 
=2.构造哈夫曼编码  
=3.构造哈夫曼解码 
====================================*/

//哈夫曼树的结点结构 
typedef struct
{
	char wei;
	int weight;//权值 
	int flag;//标记 
	int parent;// 双亲结点下一标 
	int leftChild;//左孩子下标 
	int rightChild;//右孩子下标 
 } HaffNode;
 
 //哈夫曼编码结构
typedef struct
{
 	int bit[MaxN];//存放哈夫曼编码的数组 
 	int start;//编码的起始下标 
 	int weight;//字符权值 
 }Code;
typedef struct
{
	char ch;
	int  weight;
}STR;

int sear_weight(char ch[],int weight[],char ch2[])
{
	 STR str[27]={{' ',183},{'a',64},{'b',13},{'c',22},{'d',32},{'e',103},
	             {'f',21},{'g',15},{'h',47},{'i',57},{'j',1},{'k',5},
				 {'l',32},{'m',20},{'n',57},{'o',63},{'p',15},{'q',1},
				 {'r',48},{'s',51},{'t',80},{'u',23},{'v',8},{'w',18},
				 {'x',1},{'y',16},{'z',1}};
	int i,k=0;
	
	for(i=0;ch[i]!='\0';i++)
	{
		if(ch[i]==' ')
		{
		    ch2[i]=' ';
		    weight[i]=183;
		}
		else if(ch[i]>=65&&ch[i]<=90)
		{
			k=ch[i];
			ch2[i]=ch[i];
			weight[i]=str[k-64].weight;
		}
		else if(ch[i]>=97&&ch[i]<=122)
		{
			k=ch[i];
			ch2[i]=ch[i];
			weight[i]=str[k-96].weight;
		}
		else 
		{
			return 1; 
		}
	}
}

  // 建立叶节点个数为n,权值数组为weight的哈夫曼树
void HaffTree(int weight[],int n,HaffNode haffTree[],char ch2[])
{
  	int i,j,m1,m2,x1,x2;
  	
  	//初始化哈夫曼树,n个叶结点的二叉树共有2n-1个结点
	for(i=0; i<2*n-1; i++)
	{
	  	if(i构造哈夫曼编码 
void HaffCode(HaffNode haffTree[],int n,Code haffCode[])
{
	Code *cd = (Code *)malloc(sizeof(Code));
	int i,j,child,parent;
			
	//求n个叶结点的哈夫曼编码
	for(i=0; istart = n-1;//权值越小,编码越长
		cd->weight=haffTree[i].weight;
		child=i;//从小到大依次编码 
		parent=haffTree[child].parent;
		//刨根问底->从叶结点沿路直到根结点
		while(parent !=-1)//-1根结点
		{
			if(haffTree[parent].leftChild==child)
				cd->bit[cd->start]=0;
			else 
				cd->bit[cd->start]=1;
				   
			cd->start--;//从后往前依次填码
			child=parent;
			parent=haffTree[child].parent; 
		} 
		//保存每个叶结点的信息
		for(j=cd->start+1; jbit[j];//编码
		haffCode[i].start=cd->start+1;//编码起始位 
		haffCode[i].weight=cd->weight;//权值 
		
		
	} 		  
}



void haffyima(HaffNode haffTree[],int n,char demessage[],int weight[],char message[])
{
	int i,j,k=0;
	HaffNode haffTree1;
    int len=strlen(demessage);
	for(i=0;iMaxN)
	    	{
		   		printf("n越界!!!\n");
	    		return 0;
    		}
	 
            //建树
	  		myHaffTree=(HaffNode *)malloc(sizeof(HaffNode)*(2*n-1));
	        myHaffCode=(Code *)malloc(sizeof(Code)*n);
	    	
	    	HaffTree(weight,n,myHaffTree,ch2);
	    	HaffCode(myHaffTree,n,myHaffCode);
	 

	    	for(i=0; i










你可能感兴趣的:(自写小项目,LinuxC)