2021-06-28

哈夫曼树

请为下面这段英文文本构造哈夫曼编码:
“Effificient and robust facial landmark localisation is crucial for the deployment of
real-time face analysis systems. This paper presents a new loss function, namely
Rectifified Wing (RWing) loss, for regression-based facial landmark localisation with
Convolutional Neural Networks (CNNs). We fifirst systemically analyse different loss
functions, including L2, L1 and smooth L1. The analysis suggests that the training of
a network should pay more attention to small-medium errors. Motivated by this
finding, we design a piece-wise loss that amplififies the impact of the samples with
small-medium errors. Besides, we rectify the loss function for very small errors to
mitigate the impact of inaccuracy of manual annotation

1. 请计算出每个字符出现的概率,并以概率为权重来构造哈夫曼树,写出构造 过程、画出最终的哈夫曼树,得到每个字符的哈夫曼编码。
  • 哈夫曼编码:
字母次数
21
B1
E1
M2
(2
)2
12
C2
R2
T2
L3
W3
b3
v3
N4
K4
-5
.5
,6
w8
g10
p10
y13
u14
h15
d16
c21
m22
f27
r31
l36
n41
o41
t48
a52
s53
e54
i56
104
  • 构造过程:
    ①. 从出现次数组成的数列中,找出最小的两个数,将他们两个的和加入到数列中重新排序。两个数及他们的和共同组成一个二叉树。
    ②. 重复过程1,最终数列中只剩1个值,最终的二叉树就是哈夫曼树。
  • 哈夫曼树图:
    哈夫曼树
2. 请将上述设计哈夫曼编码的过程,用代码来实现,并输出各个字母的哈夫曼 编码。(有代码,有运行结果的截图)
  • Code:
#include <iostream>
#include <map>
#include <string>
#include <cstdlib>
#include <vector>
using namespace std;

struct Huffmantree {
	int weight;
	int parent;
	int lchild;
	int rchild;
};

void CreateHuffmanCode(Huffmantree* ht, vector<string>& hc, int index, int p);
void select(Huffmantree*& ht, int i, int& s1, int& s2);
void CreatHuffmantree(Huffmantree*& ht, int n, map<char, int>number);

int main() {
	std::ios::sync_with_stdio(false);
	map<char, int> number;
	string data;
	vector<char> res;
	getline(cin, data);
	for (auto element : data)
		number[element]++;
	cout << "字符统计:" << endl;
	res.emplace_back(' ');
	for (auto element : number) {
		cout << "字符" <<  element.first << "   " << "概率:"  << element.second << endl;
		res.emplace_back(element.first);
	}
	Huffmantree* tree;
	CreatHuffmantree(tree, number.size(), number);
	vector<string> hc(number.size() + 1, "");
	cout << endl << "哈夫曼编码:" << endl;
	for (int i = 1; i <= number.size(); i++){
		CreateHuffmanCode(tree, hc, i, i);
		cout << res[i] << ":" << hc[i] << endl;
	}
}


void select(Huffmantree*& ht, int t, int& s1, int& s2){
	int j = 1;
	while (ht[j].parent != 0) j++;
	s1 = j;
	for (int i = 1; i <= t; i++){
		if (ht[i].parent == 0 && ht[i].weight <= ht[s1].weight)
		{
			s1 = i;
		}
	}
	j = 1;
	while (ht[j].parent != 0 || j == s1) j++;
	s2 = j;
	for (int i = 1; i <= t; ++i){
		if (ht[i].parent == 0 && ht[i].weight <= ht[s2].weight && i != s1){
			s2 = i;
		}
	}
}
void CreatHuffmantree(Huffmantree*& ht, int n, map<char, int>number){
	if (n <= 1) 
		return;
	int m = 2 * n - 1;
	int s1;
	int s2;
	ht = new Huffmantree[m + 1];
	for (int i = 1; i <= m; i++)
		ht[i].parent = ht[i].lchild = ht[i].rchild = 0;
	
	int i = 1;
	for (auto element : number){
		ht[i].weight = element.second;
		i++;
	}
	for (i = n + 1; i <= m; i++){
		select(ht, i - 1, s1, s2);
		ht[s1].parent = ht[s2].parent = i;
		ht[i].lchild = s1;
		ht[i].rchild = s2;
		ht[i].weight = ht[s1].weight + ht[s2].weight;
	}
}

void CreateHuffmanCode(Huffmantree* ht, vector<string>& hc, int index, int p){
	while (ht[p].parent != 0){
		int temp = ht[p].parent;
		if (ht[temp].lchild == p)  hc[index].insert(hc[index].begin(), '0');
		else if (ht[temp].rchild == p)  hc[index].insert(hc[index].begin(), '1');
		p = ht[p].parent;
	}
}


在这里插入图片描述
在这里插入图片描述

3. 请分析算法的效率,至少包括时间复杂度和空间复杂度等。
  • 时间复杂度:O(n*logn)
  • 空间复杂度:O(n)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值