哈夫曼编码

1.求哈夫曼编码最短长度和

int sumHuffmanCode(){
        while(q.size()>1){
	    int num1=q.top();q.pop();
	    int num2=q.top();q.pop();
	    ans+=num1+num2;
	    q.push(num1+num2);
        }
}

  

2.求k进制哈夫曼编码最短长度和+单行编码最短长度

int KsumHuffmanCodeandMax(){
         while(q.size()>1){
	     node now=(node){0,0};
	     for(int i=1;i<=k;i++){
		now.x+=q.top().x;
		now.m=max(now.m,q.top().m);
		q.pop();
	    }
	    now.m++;
	    sum+=now.x;
	    ans=max(ans,now.m);
	    q.push(now);
         }
}

 

3.建立哈夫曼树+求哈夫曼编码+输出哈夫曼编码

const int MAXBIT = 1e3;
const int MAXVALUE = 1e9;
typedef struct{
	int weight,parent,lchild,rchild;
	char value;
}HNodeType;
typedef struct{
	int bit[MAXBIT],start;
}HCodeType;
HNodeType HuffNode[MAXBIT];
HCodeType HuffCode[MAXBIT];

  

void Hufftree(int n){
	int x1,x2,m1,m2;
	for(int i=0;i<n-1;i++){
		m1=m2=MAXVALUE;
		x1=x2=-1;
		for(int j=0;j<n+i;j++){
			if(HuffNode[j].weight<m1&&HuffNode[j].parent==-1){
				m2=m1;
				x2=x1;
				m1=HuffNode[j].weight;
				x1=j;
			}else if(HuffNode[j].weight<m2&&HuffNode[j].parent==-1){
				m2=HuffNode[j].weight;
				x2=j;
			}
		}
		HuffNode[x1].parent=n+i;
		HuffNode[x2].parent=n+i;
		HuffNode[n+i].weight=m1+m2;
		HuffNode[n+i].lchild=x1;
		HuffNode[n+i].rchild=x2;
	}
}

  

void Huffmcode(int n){
	HCodeType tmp;
	int c,p;
	for(int i=0;i<n;i++){
		tmp.start=n-1;
		c=i;
		p=HuffNode[c].parent;
		while(p!=-1){
			if(HuffNode[p].lchild==c)tmp.bit[tmp.start]=0;
			else tmp.bit[tmp.start]=1;
			tmp.start--;
			c=p;
			p=HuffNode[c].parent;
		}
		for(int j=tmp.start+1;j<n;j++)HuffCode[i].bit[j]=tmp.bit[j];
		HuffCode[i].start=tmp.start;
	}
}

  

for(int i=0;i<n;i++){
	printf("%c: ",HuffNode[i].value);
	if(HuffCode[i].bit[HuffCode[i].start]==0)HuffCode[i].start++;
	for(int j=HuffCode[i].start;j<n;j++)cout<<HuffCode[i].bit[j];
	cout<<'\n';
}

  

 4.P1090

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,a,ans=0;
priority_queue<int,vector<int>,greater<int>>q;
int main(){
	cin>>n;
	while(n--)cin>>a,q.push(a);
	while(q.size()>1){
		int b=q.top();q.pop();
		int a=q.top();q.pop();
		ans+=a+b;
		q.push(a+b);
	}
	cout<<ans;
	return 0;
}

  

解题思路:

直接使用优先队列,每次弹出最小值,模拟即可

 

5.P2168

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct node{
	ll num,len; 
	bool operator <(node y)const{
		if(num!=y.num)return num>y.num;
		return len>y.len;
	}
	node(ll num1,ll len1):num(num1),len(len1){}
};
priority_queue<node>q;
ll n,k,x,ans=0,sum=0;
int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>x;
		q.push(node(x,0));
	}
	while((n-1)%(k-1)!=0){
		q.push(node(0,0));
		n++;
	}
	while(q.size()>1){
		node now=node(0,0);
		for(int i=1;i<=k;i++){
			now.num+=q.top().num;
			now.len=max(now.len,q.top().len);
			q.pop();
		}
		now.len++;
		sum+=now.num;
		ans=max(now.len,ans);
		q.push(now);
	}
	cout<<sum<<'\n'<<ans;
	return 0;
}

  

解题思路:

定义结构体,存储数字大小和编码长度,依次累加即可

 

6.uva240

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 100;
struct node{
	int frequ,va,id;
	node(int x=0,int y=0,int z=0){
		frequ=x;
		va=y;
		id=z;
	}
	bool operator <(const node& b)const{
		if(frequ==b.frequ)return va>b.va;
		return frequ>b.frequ;
	} 
};  
int R,xn,n,c,fre[N],father[N],code[N];
priority_queue<node>q;
int main(){
	int cas=1;
	while(cin>>R&&R){
		cin>>xn;
		memset(fre,0,sizeof(fre));
		int res=0;
		for(int i=0;i<xn;i++){
			cin>>fre[i];
			res+=fre[i];
		}
		n=xn;
		while((n-R)%(R-1)!=0)n++;
		while(q.size())q.pop();
		for(int i=0;i<n;i++)q.push(node(fre[i],i,i));
		c=n;
		int tot=0;
		while(q.size()>1){
			int sum=0,minva=n;
			for(int i=0;i<R;i++){
				sum+=q.top().frequ;
				minva=min(minva,q.top().va);
				father[q.top().id]=c;
				code[q.top().id]=i;
				q.pop();
			}
			q.push(node(sum,minva,c));
			c++;
			tot+=sum;
		}
		c--;
		printf("Set %d; average length %.2f\n",cas,tot*1.0/res);
		for(int i=0;i<xn;i++){
			int cur=i;
			string s;
			while(cur!=c){
				s+=char(code[cur]+'0');
				cur=father[cur];
			}
			reverse(s.begin(),s.end());
			cout<<"    "<<char('A'+i)<<": "<<s<<'\n';
		}
		cout<<'\n';
		cas++;
	}
	return 0;
}

  

解题思路:

定义结构体,先补全虚拟节点,再建立哈夫曼树,构造哈夫曼编码,按照题目格式输出就是答案

注意事项:

1.在c++中printf不可以直接输出string类型,需要使用c_str()函数去输出,如printf("    %c: %s\n",char('A'+i),s.c_str());

 

7.poj1521

题目链接:http://poj.org/problem?id=1521

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e2+39+7;
string s;
int mp[N];
int main(){
	while(cin>>s){
		if(s=="END")break;
		priority_queue<int,vector<int>,greater<int> >q;
		memset(mp,0,sizeof(mp));
		int len=s.length();
		
		for(int i=0;i<len;i++){
			if(s[i]=='_')mp[26]++;
			else mp[s[i]-'A']++;
		}
		
		
		for(int i=0;i<=26;i++)if(mp[i])q.push(mp[i]);
		
		
		int ans=0;
		while(q.size()>1){
			int t1=q.top();q.pop();
			int t2=q.top();q.pop();
			ans+=t1+t2;
			q.push(t1+t2);
		}
		printf("%d %d %.1f\n",8*len,ans,8.0*len/ans);
	}
	return 0;
}

  

解题思路:

和合并果子差不多,基本思路一样,只不过需要先统计字符的出现次数,在去求最短长度

 

8.求哈夫曼编码的模版

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e3+39+7;
typedef struct{
	double weight;
	int parent,lchild,rchild;
	char value;
}HNodeType;
typedef struct{
	int bit[N],start;
}HCodeType;
HNodeType HuffNode[N];
HCodeType HuffCode[N];
void HuffmanTree(int n){
	int i,j,x1,x2;double m1,m2;
	for(i=0;i<n-1;i++){
		m1=m2=1e9;x1=x2=-1;
		for(j=0;j<n+i;j++){
			if(HuffNode[j].weight<m1&&HuffNode[j].parent==-1){
				m2=m1;
				m1=HuffNode[j].weight;
				x2=x1;
				x1=j;
			}else if(HuffNode[j].weight<m2&&HuffNode[j].parent==-1){
				m2=HuffNode[j].weight;
				x2=j;
			}
		}
		HuffNode[x1].parent=n+i;
		HuffNode[x2].parent=n+i;
		HuffNode[n+i].weight=m1+m2;
		HuffNode[n+i].lchild=x1;
		HuffNode[n+i].rchild=x2;
	}
} 
void HuffmanCode(HCodeType HuffCode[],int n){
	HCodeType cd;
	int i,j,c,p;
	for(i=0;i<n;i++){
		cd.start=n-1;
		c=i;
		p=HuffNode[c].parent;
		while(p!=-1){
			if(HuffNode[p].lchild==c)cd.bit[cd.start]=0;
			else cd.bit[cd.start]=1;
			cd.start--;
			c=p;
			p=HuffNode[c].parent;
		}
		for(j=cd.start+1;j<n;j++)HuffCode[i].bit[j]=cd.bit[j];
		HuffCode[i].start=cd.start;
	}
}
int main(){
	for(int i=0;i<N;i++)HuffNode[i].parent=HuffNode[i].lchild=HuffNode[i].rchild=-1;
	int n;cin>>n;
	for(int i=0;i<n;i++){
		char c;double w;
		cin>>c>>w;
		HuffNode[i].value=c;
		HuffNode[i].weight=w;
	}
	HuffmanTree(n);
	HuffmanCode(HuffCode,n);
	for(int i=0;i<n;i++){
		cout<<HuffNode[i].value<<": ";
		for(int j=HuffCode[i].start+1;j<n;j++)cout<<HuffCode[i].bit[j];
		cout<<'\n';
	}
	return 0;
}

  

posted @ 2023-02-28 11:45  天雷小兔  阅读(52)  评论(0)    收藏  举报