JS实现的哈夫曼编码示例【原始版与修改版】


Posted in Javascript onApril 22, 2018

本文实例讲述了JS实现的哈夫曼编码。分享给大家供大家参考,具体如下:

原始版

function cal(str) {
  if (typeof str !== 'string' || str.length < 1) {
    return;
  }
  var map = {};
  var i = 0;
  while(str[i]) {
    map[str[i]] ? map[str[i]]++ : (map[str[i]] = 1);
    i++;
  }
  return map;
}
function sort(map) {
  map = map || {};
  var result = [];
  for (key in map) {
    if(map.hasOwnProperty(key)) {
      var obj = {
        key: key,
        val: map[key]
      };
      result.push(new Node(null, null, obj));
    }
  }
  return result.sort(function(x,y){return x.data.val > y.data.val});
}
function Node(left, right, data) {
  this.left = left;
  this.right = right;
  this.data = data;
}
function makeTree(table) {
  var i = 0;
  var len = table.length;
  var node1;
  var node2;
  var parentNode;
  while(table.length > 1) {
    parentNode = new Node(table[i], table[i+1], {key: null, val: table[i]['data'].val + table[i+1]['data'].val});
    table.splice(i,2);
    table.unshift(parentNode);
    table.sort(function(x,y){return x.data.val > y.data.val});
  }
  return table;
}
function encode(str, ret) {
  if (typeof str !== 'string' || str.length < 1) {
    return;
  }
  var i = 0;
  var result = '';
  while(str[i]) {
    result += ret[str[i++]];
  }
  return result
}
function reverseRet(ret) {
  var result = {};
  for (key in ret) {
    if(ret.hasOwnProperty(key)) {
      result[ret[key]] = key;
    }
  }
  return result;
}
function decode(str, ret) {
  var i = 0;
  var result = '';
  var data = '';
  var map = reverseRet(ret);
  while(str) {
    result += str[i++];
    if (result in map) {
      data += map[result];
      str = str.replace(new RegExp("^"+result),'');
      result = '';
      i = 0;
    }
  }
  console.log(data)
}
function traversal(tree, code, ret) {
  if (tree.left !== null) {
    traversal(tree.left, code + '0', ret);
  } else {
    ret[tree.data.key] = code;
  }
  if (tree.right !== null) {
    traversal(tree.right,code + '1', ret);
  } else {
    ret[tree.data.key] = code;
  }
}
var ret = {};
var str = 'ew qew qd ef 24 gf ewr getElementsByTagName';
traversal(makeTree(sort(cal(str)))[0],'', ret)
decode(encode(str, ret), ret)
btoa(encode(str,ret))

修改版

function Huffman(str) {
  // 需要编码的字符串
  this.str = str;
  // 键和频率映射表
  this.keyCountMap = null;
  // 编码和键的映射表
  this.codeKeyMap = {};
  // 键和编码的映射表
  this.keyCodeMap = {};
  // 哈夫曼树节点列表
  this.nodeList = null;
  // 哈夫曼树根节点
  this.root = null;
  // 哈夫曼编码后的01序列
  this.code = null;
}
Huffman.prototype.cal = function cal() {
  str = this.str;
  var map = {};
  var i = 0;
  while(str[i]) {
    map[str[i]] ? map[str[i]]++ : (map[str[i]] = 1);
    i++;
  }
  this.keyCountMap = map;
}
Huffman.prototype.sort = function sort() {
  map = this.keyCountMap;
  var result = [];
  for (key in map) {
    if(map.hasOwnProperty(key)) {
      var obj = {
        key: key,
        val: map[key]
      };
      result.push(new Node(null, null, obj));
    }
  }
  this.nodeList = result.sort(function(x,y){return x.data.val > y.data.val});
}
function Node(left, right, data) {
  this.left = left;
  this.right = right;
  this.data = data;
}
Huffman.prototype.makeTree = function makeTree() {
  var i = 0;
  var len = this.nodeList.length;
  var node1;
  var node2;
  var parentNode;
  var table = this.nodeList;
  while(table.length > 1) {
    parentNode = new Node(table[i], table[i+1], {key: null, val: table[i]['data'].val + table[i+1]['data'].val});
    table.splice(i,2);
    table.unshift(parentNode);
    table.sort(function(x,y){return x.data.val > y.data.val});
  }
  this.root = table[0] || new Node();
  return this.root;
}
Huffman.prototype.traversal = function traversal(tree, code) {
  if (tree.left !== null) {
    traversal.call(this,tree.left, code + '0');
  } else {
    this.keyCodeMap[tree.data.key] = code;
  }
  if (tree.right !== null) {
    traversal.call(this, tree.right,code + '1');
  } else {
    this.keyCodeMap[tree.data.key] = code;
  }
}
Huffman.prototype.encode = function encode() {
  this.cal();
  this.sort();
  var root = this.makeTree();
  this.traversal(root, '');
  var ret = this.keyCodeMap;
  var i = 0;
  var result = '';
  var str = this.str;
  while(str[i]) {
    result += ret[str[i++]];
  }
  this.code = result;
  console.log('encode:' + result);
  return result
}
Huffman.prototype.reverseMap = function reverseMap() {
  var ret = this.keyCodeMap;
  var result = {};
  for (key in ret) {
    if(ret.hasOwnProperty(key)) {
      result[ret[key]] = key;
    }
  }
  this.codeKeyMap = result;
  return result;
}
Huffman.prototype.decode = function decode() {
  var i = 0;
  var result = '';
  var data = '';
  var map = this.reverseMap();
  var str = this.code;
  while(str) {
    result += str[i++];
    if (result in map) {
      data += map[result];
      str = str.replace(new RegExp("^"+result),'');
      result = '';
      i = 0;
    }
  }
  console.log("decode:" + data)
}
Huffman.prototype.encodeBase64 = function() {
  try {
    var base64 = btoa(this.code);
    return base64;
  } catch(e) {
    return '';
  }
}
var str = 'ew qew qd ef 24 gf ewr getElementsByTagName';
var huffman = new Huffman(str)
huffman.encode(str)
huffman.decode();
huffman.encodeBase64();

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
动态调用css文件——jquery的应用
Feb 20 Javascript
JavaScript高级程序设计(第3版)学习笔记12 js正则表达式
Oct 11 Javascript
html超链接打开窗口大小的方法
Mar 05 Javascript
js获取当前日期时间及其它操作汇总
Apr 17 Javascript
javascript类型系统 Array对象学习笔记
Jan 09 Javascript
Bootstrap导航条鼠标悬停下拉菜单
Jan 04 Javascript
layui表格实现代码
May 20 Javascript
mongoose设置unique不生效问题的解决及如何移除unique的限制
Nov 07 Javascript
vue.js 实现输入框动态添加功能
Jun 25 Javascript
使用js在layui中实现上传图片压缩
Jun 18 Javascript
浅析vue-cli3配置webpack-bundle-analyzer插件【推荐】
Oct 23 Javascript
JS简单表单验证功能完整示例
Jan 26 Javascript
使用Angular CLI快速创建Angular项目的一些基本概念和写法小结
Apr 22 #Javascript
Vue下滚动到页面底部无限加载数据的示例代码
Apr 22 #Javascript
关于Angularjs中自定义指令一些有价值的细节和技巧小结
Apr 22 #Javascript
jQuery中图片展示插件highslide.js的简单dom
Apr 22 #jQuery
手写简单的jQuery雪花飘落效果实例
Apr 22 #jQuery
JQuery元素快速查找与操作
Apr 22 #jQuery
javaScript产生随机数的用法小结
Apr 21 #Javascript
You might like
PHP正则表达式替换站点关键字链接后空白的解决方法
2014/09/16 PHP
基于php实现随机合并数组并排序(原排序)
2015/11/26 PHP
PHP isset()与empty()的使用区别详解
2017/02/10 PHP
基于JavaScript 下namespace 功能的简单分析
2013/07/05 Javascript
extjs中form与grid交互数据(record)的方法
2013/08/29 Javascript
JavaScript中使用stopPropagation函数停止事件传播例子
2014/08/27 Javascript
nodejs中实现路由功能
2014/12/29 NodeJs
JavaScript实现表格快速变色效果代码
2015/08/19 Javascript
第四篇Bootstrap网格系统偏移列和嵌套列
2016/06/21 Javascript
通过JS和PHP两种方法判断用户请求时使用的浏览器类型
2016/09/01 Javascript
Ubuntu 16.04 64位中搭建Node.js开发环境教程
2016/10/19 Javascript
基于jquery实现的鼠标悬停提示案例
2016/12/11 Javascript
微信小程序实现图片轮播及文件上传
2017/04/07 Javascript
socket.io实现在线群聊功能
2017/04/07 Javascript
基于Vue、Vuex、Vue-router实现的购物商城(原生切换动画)效果
2018/01/09 Javascript
vue+ESLint 配置保存 自动格式化代码
2020/03/17 Javascript
获取Django项目的全部url方法详解
2017/10/26 Python
tensorflow获取变量维度信息
2018/03/10 Python
浅谈解除装饰器作用(python3新增)
2018/10/15 Python
numpy给array增加维度np.newaxis的实例
2018/11/01 Python
Python程序控制语句用法实例分析
2020/01/14 Python
全球领先美式家具品牌:Ashley爱室丽家居
2017/08/07 全球购物
新西兰航空中国官网:Air New Zealand China
2018/07/24 全球购物
澳大利亚排名第一的露营和户外设备在线零售商:Outbax
2020/05/06 全球购物
试述DBMS的主要功能
2016/11/13 面试题
中专生学习生活的自我评价分享
2013/10/27 职场文书
品管员岗位职责
2013/11/10 职场文书
高二生物教学反思
2014/01/27 职场文书
《独坐敬亭山》教学反思
2014/04/08 职场文书
幼儿园课题实施方案
2014/05/14 职场文书
巴西世界杯32强口号
2014/06/05 职场文书
诚实守信演讲稿
2014/09/01 职场文书
解除合同协议书范本
2016/03/21 职场文书
《鲁滨逊漂流记》之六读后感(4篇)
2019/09/29 职场文书
Python 中数组和数字相乘时的注意事项说明
2021/05/10 Python
Nginx部署vue项目和配置代理的问题解析
2021/08/04 Servers