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 相关文章推荐
IE php关于强制下载文件的代码
Aug 23 Javascript
JavaScript字符串对象substring方法入门实例(用于截取字符串)
Oct 17 Javascript
javaScript中slice函数用法实例分析
Jun 08 Javascript
jquery地址栏链接与a标签链接匹配之特效代码总结
Aug 24 Javascript
前端js实现文件的断点续传 后端PHP文件接收
Oct 14 Javascript
详解vue父子组件间传值(props)
Jun 29 Javascript
微信小程序开发animation心跳动画效果
Aug 16 Javascript
关于react-router/react-router-dom v4 history不能访问问题的解决
Jan 08 Javascript
js中时间格式化的几种方法
Jul 22 Javascript
手挽手带你学React之React-router4.x的使用
Feb 14 Javascript
js new Date()实例测试
Oct 31 Javascript
优化Vue中date format的性能详解
Jan 13 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
详解Yii2高级版引入bootstrap.js的一个办法
2017/03/21 PHP
ExtJS GTGrid 简单用户管理
2009/07/01 Javascript
jquery获取下拉列表的值为null的解决方法
2011/03/18 Javascript
一个基于jquery的文本框记数器
2012/09/19 Javascript
js异常捕获方法介绍
2013/04/10 Javascript
关于JavaScript与HTML的交互事件
2013/04/12 Javascript
jQuery自定义添加&quot;$&quot;与解决&quot;$&quot;冲突的方法
2015/01/19 Javascript
使用Sticker.js实现贴纸效果
2015/01/28 Javascript
AspNet中使用JQuery boxy插件的确认框
2015/05/20 Javascript
JavaScript操作HTML元素和样式的方法详解
2015/10/21 Javascript
vuejs父子组件之间数据交互详解
2017/08/09 Javascript
vue+vue-validator 表单验证功能的实现代码
2017/11/13 Javascript
基于Vue自定义指令实现按钮级权限控制思路详解
2018/05/23 Javascript
React中使用UMEditor的方法示例
2019/12/27 Javascript
vue 通过绑定事件获取当前行的id操作
2020/07/27 Javascript
vue+高德地图实现地图搜索及点击定位操作
2020/09/09 Javascript
[13:16]INFAMOUS vs VGJ T BO3
2018/06/07 DOTA
Python version 2.7 required, which was not found in the registry
2014/08/26 Python
Python中几种操作字符串的方法的介绍
2015/04/09 Python
Python实现自动为照片添加日期并分类的方法
2017/09/30 Python
python异步实现定时任务和周期任务的方法
2019/06/29 Python
在自动化中用python实现键盘操作的方法详解
2019/07/19 Python
Python有参函数使用代码实例
2020/01/06 Python
体育教育专业毕业生自荐信
2013/11/15 职场文书
颁奖典礼主持词
2014/03/25 职场文书
《小动物过冬》教学反思
2014/04/17 职场文书
奉献演讲稿范文
2014/05/21 职场文书
禁止酒驾标语
2014/06/25 职场文书
创先争优标语
2014/06/27 职场文书
小学教师工作总结2015
2015/04/07 职场文书
运动会报道稿大全
2015/07/23 职场文书
初中政治教师教学反思
2016/02/23 职场文书
工作违纪的检讨书范文
2019/07/09 职场文书
史上最全书信经典范文大全(建议收藏)
2019/07/10 职场文书
python中的random模块和相关函数详解
2022/04/22 Python
一次SQL查询优化原理分析(900W+数据从17s到300ms)
2022/06/10 SQL Server