霍夫曼编码(含完整源码)

1.第一步 统计所有的字符【*】出现的频次并按频次进行从小到大的排序
2.第二步 进行权值的合并
在这里插入图片描述
3.第三步 编码 左0 右 1
在这里插入图片描述
在这里插入图片描述
huffman编码大致分为以下步骤:

  1. 统计所有字符出现的频次
  2. 构建huffman树
  3. huffman树生成huffman编码
  4. 将源文件压缩成huffman编码结构
  5. 收到源文件之后利用Huffman树进行Huffman解码

定义huffman树的数据结构

// huffman编码数据结构
class HuffmanNode{
    constructor(char,frequency) {
        this.char = char
        this.frequency = frequency
        this.left = null
        this.right = null
    }
}

统计字频

// 统计频次
const countFrequency = function () {
    const data = fs.readFileSync(path.resolve(__dirname, './a.txt'))
    const dataTxt = data.toString();
    const map = new Map();
    // 计算频次
    for (let index = 0; index < dataTxt.length; index++) {
        const element = dataTxt[index];
        if (map.has(element)) {
            map.set(element, map.get(element) + 1);
        } else {
            map.set(element, 1);
        }
    }
    return map;
}

构建huffman树

/**
 * 构建huffman树
 * @param {Map<char,number>} frequency 
 */
const buildHuffmanTree = function (frequency) {
    const keyValues = Array.from(frequency);
    const nodes = []
    for (const [key,value] of keyValues) {
        const huffmanNodeItem = new HuffmanNode(key, value)
        nodes.push(huffmanNodeItem)
    }
    while (nodes.length > 1) {
        // 从大到小排序
        nodes.sort((a, b) => b.frequency - a.frequency)
        // 取最小的两个
        leftNode = nodes.pop()
        rightNode = nodes.pop();
        // 最小的node合并成一个新的huffman节点
        parentNode = new HuffmanNode(null, leftNode.frequency + rightNode.frequency);
        parentNode.left = leftNode
        parentNode.right = rightNode
        nodes.push(parentNode)
    }
    return nodes[0]
}

生成huffman编码

利用huffman树生成huffman编码

/**
 * 将huffman树生成huffman编码
 * @param {HuffmanNode} huffmanTree 
 * @returns 
 */
const huffmanCode = function (huffmanTree) {
    const result = new Map();
    const dfs = function (huffmanTree, str) {
        if (huffmanTree && huffmanTree.left && huffmanTree.right) {
            dfs(huffmanTree.left, str + '0')
            dfs(huffmanTree.right,str+'1')
        } else {
            result.set(huffmanTree.char, str)
            return;
        }
    }
    dfs(huffmanTree, '');
    return result;
}

huffman编码

/**
 * 霍夫曼编码
 * @returns 
 */
const HuffmanEncode = function() {
    const data = fs.readFileSync(path.resolve(__dirname, './a.txt'))
    const dataTxt = data.toString();
    let result = ''
    for (let index = 0; index < dataTxt.length; index++) {
        const element = dataTxt[index];
        result+= codes.get(element)
    }
    fs.writeFileSync(path.resolve(__dirname, './b.txt'), result)
    return result;
}

huffman解码

/**
 * 霍夫曼解码
 * @param {*} huffmanTree 
 * @param {*} source 
 */
function HUffmanDecode(huffmanTree,source){
    let current = huffmanTree
    let result = ''
    for (let index = 0; index < source.length; index++) {
        const element = source[index];
        if (element == '0') {
            current = current.left
            if (current.char != null) {
                result += current.char;
                current = huffmanTree;
            }
        } else {
            current = current.right;
            if (current.char != null) {
                result += current.char;
                current = huffmanTree;
            }
        }
    }
    fs.writeFileSync(path.resolve(__dirname,'./c.txt'),result)
}

完整代码

运行环境 Nodejs
需要将代码保存为 .js类型文件
并在.js文件所在文件夹下放一个a.txt文件方可成功运行
a.txt文件为需要进行编码的源文本,建议为英文

const fs = require('fs')
const path = require('path');
// 统计频次
const countFrequency = function () {
    const data = fs.readFileSync(path.resolve(__dirname, './a.txt'))
    const dataTxt = data.toString();
    const map = new Map();
    // 计算频次
    for (let index = 0; index < dataTxt.length; index++) {
        const element = dataTxt[index];
        if (map.has(element)) {
            map.set(element, map.get(element) + 1);
        } else {
            map.set(element, 1);
        }
    }
    return map;
}
// huffman编码数据结构
class HuffmanNode{
    constructor(char,frequency) {
        this.char = char
        this.frequency = frequency
        this.left = null
        this.right = null
    }
}
/**
 * 构建huffman树
 * @param {Map<char,number>} frequency 
 */
const buildHuffmanTree = function (frequency) {
    const keyValues = Array.from(frequency);
    const nodes = []
    for (const [key,value] of keyValues) {
        const huffmanNodeItem = new HuffmanNode(key, value)
        nodes.push(huffmanNodeItem)
    }
    while (nodes.length > 1) {
        // 从大到小排序
        nodes.sort((a, b) => b.frequency - a.frequency)
        // 取最小的两个
        leftNode = nodes.pop()
        rightNode = nodes.pop();
        // 最小的node合并成一个新的huffman节点
        parentNode = new HuffmanNode(null, leftNode.frequency + rightNode.frequency);
        parentNode.left = leftNode
        parentNode.right = rightNode
        nodes.push(parentNode)
    }
    return nodes[0]
}
const frequency = countFrequency()
const huffmanTree = buildHuffmanTree(frequency)
fs.writeFileSync(path.resolve(__dirname, './huffmanTree.json'), JSON.stringify(huffmanTree))
/**
 * 将huffman树生成huffman编码
 * @param {HuffmanNode} huffmanTree 
 * @returns 
 */
const huffmanCode = function (huffmanTree) {
    const result = new Map();
    const dfs = function (huffmanTree, str) {
        if (huffmanTree && huffmanTree.left && huffmanTree.right) {
            dfs(huffmanTree.left, str + '0')
            dfs(huffmanTree.right,str+'1')
        } else {
            result.set(huffmanTree.char, str)
            return;
        }
    }
    dfs(huffmanTree, '');
    return result;
}
const codes = huffmanCode(huffmanTree);
/**
 * 霍夫曼编码
 * @returns 
 */
const HuffmanEncode = function() {
    const data = fs.readFileSync(path.resolve(__dirname, './a.txt'))
    const dataTxt = data.toString();
    let result = ''
    for (let index = 0; index < dataTxt.length; index++) {
        const element = dataTxt[index];
        result+= codes.get(element)
    }
    fs.writeFileSync(path.resolve(__dirname, './b.txt'), result)
    return result;
}
const result = HuffmanEncode()
/**
 * 霍夫曼解码
 * @param {*} huffmanTree 
 * @param {*} source 
 */
function HuffmanDecode(huffmanTree,source){
    let current = huffmanTree
    let result = ''
    for (let index = 0; index < source.length; index++) {
        const element = source[index];
        if (element == '0') {
            current = current.left
            if (current.char != null) {
                result += current.char;
                current = huffmanTree;
            }
        } else {
            current = current.right;
            if (current.char != null) {
                result += current.char;
                current = huffmanTree;
            }
        }
    }
    fs.writeFileSync(path.resolve(__dirname,'./c.txt'),result)
}
HuffmanDecode(huffmanTree,result)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript入门--数组

JavaScript入门--数组 前言数组的操作1、在数组的尾部添加元素2、删除数组尾部的元素&#xff0c;也就是最后一个元素3、删除头部第一个元素4、在数组的前面添加元素 小案例5、数组的翻转6、数组的排序7、数组的合并8、数组的切片 前言 JS中的数组类似于python中的列表&#x…

软件设计:UML 模型图总结

1. 相关链接 参考教程&#xff1a; https://sparxsystems.com/resources/tutorials/ https://sparxsystems.com/enterprise_architect_user_guide/15.2/model_domains/whatisuml.html Unified Modeling Language (UML) description, UML diagram examples, tutorials and r…

产品经理技术脑:怎么看懂接口文档

日常产品开发过程中&#xff0c;涉及前后端数据交互的时候&#xff0c;往往会离不开接口调用&#xff0c;尽管产品经理一般不需要写接口文档&#xff08;负责接口中间层产品经理除外&#xff09;&#xff0c;但对接口了解&#xff0c;对于需求沟通、需求传达还是很有帮助的。 …

集成电路测试学习

集成电路&#xff08;Integrated Circuit&#xff0c;IC&#xff09;整个设计流程包括&#xff1a;电路设计、晶圆制造、晶圆测试、IC封装、封装后测试。 IC测试目的&#xff1a;一、确认芯片是否满足产品手册上定义的规范&#xff1b;二、通过测试测量&#xff0c;确认芯片可以…

【艾体宝方案】智驾未来:高性能实时数据库,车企的数据分析变革!

近年来&#xff0c;汽车行业持续朝向互联互通以及自动化方向的演进&#xff0c;无论是在优化制造流程、提升车辆安全与性能&#xff0c;还是提供定制化客户体验方面&#xff0c;汽车行业的都未来牢牢根植于其有效处理和利用数据的能力。 一、汽车行业面临的挑战 &#xff08;…

Java(120):使用Java对TiDB数据库批量写入数据

使用Java对TiDB数据库批量写入数据 1、前言&#xff1a; 本次对TiDB数据库测试需要1w条数据&#xff0c;如果MySQL可用存储过程造数&#xff0c;结果发现TiDB用不了。只能想其他办法&#xff0c;一种是Java直接批量插入&#xff0c;一种是Jmeter插入。这里用的Java插入。 如果…

CANoe中关于NetworkHardwareConfiguration中的setup设置参数的详解

前提说明 本文是以VN1640A中的CAN_FD工程为例&#xff0c;为大家讲解。 1&#xff1a;首先打开相关配置 重点讲解红色框中的参数&#xff0c;其他参数该如何设置&#xff0c;请参考我另外一篇文章“关于CANoe硬件及接口的学习笔记&#xff08;VN1640A&#xff09;”或自行查阅…

js 写 视频轮播

html代码 <div class"test_box"> <div class"test"> <a href"#"> <div class"test_a_box"> <div class"test_a_mask"></div> <div class"test_a_layer"> <div cla…

偏微分方程算法之混合边界差分

目录 一、研究对象 二、差分格式 2.1 向前欧拉格式 1. 中心差商 1.1.1 理论推导 1.1.2 算例实现 2. x0处向前差商&#xff0c;x1处向后差商 1.2.1 理论推导 1.2.2 算例实现 2.2 Crank-Nicolson格式 2.2.1 理论推导 2.2.2 算例实现 一、研究对象 这里我们以混合边界…

高分一号卫星(GF-1):中国遥感科技的骄傲

高分一号卫星&#xff08;GF-1&#xff09;是中国遥感科技领域的一项突破性成就&#xff0c;其引入了先进的成像技术和灵活的数据获取模式&#xff0c;为中国的资源管理、环境监测和城市规划等领域带来了巨大的变革。本文将深入介绍高分一号卫星的技术参数、成像能力以及应用场…

抽奖系统设计

如何设计一个百万级用户的抽奖系统&#xff1f; - 掘金 如何设计百万人抽奖系统…… 在实现抽奖逻辑时&#xff0c;Redis 提供了多种数据结构&#xff0c;选择哪种数据结构取决于具体的抽奖规则和需求。以下是一些常见场景下推荐使用的Redis数据结构&#xff1a; 无序且唯一奖…

解析数据科学,探索ChatGPT背后的奥秘

在当今这个由数据驱动和AI蓬勃发展的时代&#xff0c;数据科学作为一门融合多种学科的综合性领域&#xff0c;对于推动各行各业实现数字化转型升级起着至关重要的作用。近年来&#xff0c;大语言模型技术发展态势强劲&#xff0c;为数据科学的进步做出了巨大贡献。其中&#xf…

第四百六十二回

文章目录 1. 概念介绍2. 实现方法3. 示例代码4. 内容总结 我们在上一章回中介绍了"关于MediaQuery的优化"相关的内容&#xff0c;本章回中将介绍readMore这个三方包.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章回中介绍的readMore是一个…

新经济助推高质量发展“大有云钞”聚焦未来趋势

近日&#xff0c;由大有云钞科技&#xff08;北京&#xff09;有限公司主办的一场关于“新经济助力高质量发展法治研讨会”在北京国家会议中心隆重举行。此次研讨会汇聚了来自政府、企业、学术界和法律界的众多专家学者&#xff0c;共同探讨新经济背景下的法治建设和高质量发展…

Scrapy 框架基础

Scrapy框架基础Scrapy框架进阶 Scrapy 框架基础 【一】框架介绍 【1】简介 Scrapy是一个用于网络爬取的快速高级框架&#xff0c;使用Python编写他不仅可以用于数据挖掘&#xff0c;还可以用于检测和自动化测试等任务 【2】框架 官网链接https://docs.scrapy.org/en/late…

YesPMP平台 | 活动有礼,现金奖励点击领取!

YesPMP众包平台在线发福利啦&#xff0c;活动火热开启&#xff0c;现金奖励等你来领&#xff0c;最高可领千元&#xff0c;赶快参与将奖励收入囊中&#xff0c;一起来了解活动细节吧&#xff01; 一、活动内容&#xff1a; 活动一&#xff1a;【项目征集令】活动&#xff0c;…

二路归并排序的算法设计和复杂度分析(C语言)

目录 实验内容&#xff1a; 实验过程&#xff1a; 1.算法设计 2.程序清单 3.运行结果 4.算法复杂度分析 实验内容&#xff1a; 二路归并排序的算法设计和复杂度分析。 实验过程&#xff1a; 1.算法设计 二路归并排序算法&#xff0c;分为两个阶段&#xff0c;首先对待排…

Anaconda下的tensorflow安装

关于Anaconda的安装以及配置可以浏览我的上一篇博客Anaconda的安装与配置 下面是安装tensorflow的命令&#xff0c;使用下列指令安装前需要配置好CUDA&#xff0c;关于CUDA的配置在上一篇博客中有详细的步骤描述。 关于官方环境配置的要求可以浏览官网&#xff1a;https://t…

每帧纵享丝滑——ToDesk云电脑、网易云游戏、无影云评测分析及ComfyUI部署

目录 一、前言二、云电脑性能测评分析2.1、基本配置分析2.1.1、处理器方面2.1.2、显卡方面2.1.3、内存与存储方面2.1.4、软件功能方面 2.2、综合跑分评测 三、软件应用实测分析3.1、云电竞测评3.2、AIGC科研测评——ComfyUI部署3.2.1、下载与激活工作台3.2.2、加载模型与体验3.…

yolov8目标检测 部署瑞芯微rk3588记录

1. 前置条件 本地电脑系统&#xff0c;ubuntu20.04 训练代码&#xff1a; 训练代码下载的ultralytics官方代码 SHA&#xff1a;6a2fddfb46aea45dd26cb060157d22cf14cd8c64 训练代码仅做数据修改&#xff0c;类别修改&#xff0c;代码结构未做任何修改 需要准备的代码&#…