基础算法之Huffman编码

// Type your code here, or load an example.
#include<iostream>
#include<string>
#include<queue>
#include <unordered_map>
#include <vector>using namespace std;//树节点结构
struct Node
{char ch;int freq;Node *left;Node *right;Node(char ch, int freq) : ch(ch), freq(freq), left(nullptr), right(nullptr) {};Node(char ch, int freq, Node* left, Node* right) : ch(ch), freq(freq), left(left), right(right) {};};//比较函数,用于优先队列
struct Compare
{bool operator()(Node * l,Node * r){return l->freq > r->freq;}
};//遍历HUffman树,存储编码
void encode(Node * root,string str,unordered_map<char,string> &huffmanCode)
{if(root==nullptr){return;}//既没有左子节点又没有右子节点if(!root->left && !root->right){huffmanCode[root->ch] = str;}//二叉树分支,左边是0,右边是1//二叉树末端节点是编码encode(root->left,str+'0',huffmanCode);encode(root->right,str+'1',huffmanCode);
}//构建Huffman树,并返回根节点
Node* buildHuffmanTree(string text)
{//将字符串中字符按照频率出现次数进行统计unordered_map<char, int> freq;for (char ch : text) {freq[ch]++;}//使用优先队列,构建Huffman树//Node* 表示元素类型//vector<Node*>使用底层容器,作为队列//比较函数对象,用于确定队列中元素的顺序priority_queue<Node*, vector<Node*>, Compare> pq;for (auto pair : freq) {pq.push(new Node(pair.first, pair.second));}while (pq.size() != 1) {Node *left = pq.top(); pq.pop();Node *right = pq.top(); pq.pop();int sum = left->freq + right->freq;pq.push(new Node('\0', sum, left, right));}return pq.top();
}int main() {string text="AAAAABCD";cout << "输入一个字符串: ";//getline(cin, text);Node* root = buildHuffmanTree(text);unordered_map<char, string> huffmanCode;encode(root, "", huffmanCode);string strEncoded;for (char ch : text) {strEncoded += huffmanCode[ch];}cout << "ASCII编码长度: " << text.length() * 8 << " bits\n";cout << "Huffman编码长度: " << strEncoded.length() << " bits\n";cout << "压缩比: " << (text.length() * 8.0 / strEncoded.length()) << "\n";return 0;
}

在这里插入图片描述

1举例子

当然,我将根据提供的代码逐步解释如何为例子中的字符串 “beep boop beer!” 构建Huffman树并返回根节点。我们按照代码中的步骤来操作。

首先,我们需要统计字符串中每个字符的频率。在我们的例子中,字符频率如下:

  • ‘b’: 3
  • ‘e’: 5
  • ‘p’: 2
  • ‘o’: 2
  • ’ ': 2 (空格字符)
  • ‘r’: 1
  • ‘!’: 1

代码中的 buildHuffmanTree 函数负责构建Huffman树。下面是函数中的关键步骤:

  1. 统计频率:
    这一步通过遍历整个字符串并使用一个哈希表(unordered_map<char, int>)来计算每个字符的出现次数。

  2. 创建初始节点:
    对于每个唯一字符,我们创建一个新的 Node,包含字符(ch)和频率(freq)。这些节点被加入到优先队列(priority_queue)中,该队列使用自定义的比较函数 Compare 对节点进行排序,以确保频率最低的节点位于队列的顶部。

  3. 构建树:
    然后,我们进入一个循环,直到优先队列中只剩下一个节点为止。在每次循环中,我们执行以下操作:<

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/438308.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode: Z 字形变换 + 模拟】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

产业需求大数据平台

产业需求大数据平台&#xff0c;依托大数据、NLP等技术&#xff0c;全面采集区域产业人才需求数据&#xff0c;从宏观、中观、微观三个层面对产业需求进行分析&#xff0c;并匹配学校自身的办学定位、专业布局、人才培养目标、培养规格和课程设置&#xff0c;进行专业设置匹配度…

MySQL-进阶-存储引擎

一、MySQL体系结构 二、存储引擎简介 三、存储引擎特点 1、InnoDB 2、MyISAM 3、Memory 四、存储引擎选择

如何发现帕鲁私服漏洞

白天当帕鲁、晚上抓帕鲁 相信所有的帕鲁玩家都不希望辛辛苦苦肝了几百小时抓的帕鲁因为网络入侵消失&#xff0c;除了抵御游戏内的强盗入侵&#xff0c;还要抵御现实世界的网络入侵&#xff0c;原本单纯的帕鲁变的复杂无比。 服务器弱口令、服务漏洞、未授权访问等入侵手段&a…

STM32学习笔记(三) —— GPIO点亮LED

1.GPIO简介 GPIO&#xff0c;全称是General-purpose input/output&#xff08;通用输入输出&#xff09;。在单片机中是表示能被控制的引脚&#xff0c;能检测输入信号的高低电平&#xff0c;也能输出高低电平控制外部设备。STM32F103RCT6一共有64个引脚&#xff0c;其中有51个…

二维数组的学习

前言 在前面我们学习了一维数组&#xff0c;但是有的问题需要用二位数组来解决。 二维数组常称为矩阵&#xff0c;把二维数组写成行和列的排列形式&#xff0c;可以有助于形象化的理解二维数组的逻辑结构。 一、二维数组的定义 二维数组定义的一般格式&#xff1a; 数据类型 数…

Mac安装及配置MySql

Mac下载配置MySql mysql下载及安装 下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 根据自己电脑确定下载x86还是ARM版本的 如果不确定&#xff0c;可以查看自己电脑版本&#xff0c;终端输入命令 uname -a 点击Download下载&#xff0c;可跳过登录注册&…

笨蛋总结JVM

笨蛋总结JVM 由于Java语言将自己的内存控制权交给了虚拟机&#xff0c;所以需要了解虚拟机的运行机制 &#xff08;主要用于回顾JVM&#xff09; 笨蛋总结JVM 笨蛋总结JVM1.运行时数据区域线程私有区域程序计数器Java虚拟机栈本地方法栈 线程共享区域堆方法区 1.2程序计数器…

ctfshow web71

开启环境&#xff1a; c?><?php $anew DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString(). );} exit(0); ?> cinclude("/flagc.txt");exit();

SD-WAN技术:异地组网监控的革新之选

在当今数字化的商业环境中&#xff0c;企业对于远程监控的需求日益增长。无论是分支机构的管理&#xff0c;还是跨地域的项目协作&#xff0c;稳定、高效的网络监控系统都显得至关重要。然而&#xff0c;异地组网监控面临着数据传输、设备兼容性、安全性等一系列挑战。在这一背…

GUN/Linux时间同步服务之chrony配置管理

风险告知 本人及本篇博文不为任何人及任何行为的任何风险承担责任&#xff0c;图解仅供参考&#xff0c;请悉知&#xff01;相关配置操作是在一个全新的演示环境下进行的&#xff0c;演示环境中没有任何有价值的数据&#xff0c;但这并不代表摆在你面前的环境也是如此。生产环境…

springboot设置热部署

目录 以下是实现 Spring Boot 热部署的方法&#xff1a; 1、添加依赖 2、配置 IDE 3、配置 application.properties 或 application.yml 4、启动应用 Spring Boot 提供了开发者进行热部署的支持。在开发过程中&#xff0c;每次修改代码后&#xff0c;需要重启应用才能看到…