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 相关文章推荐
js同时按下两个方向键
Dec 01 Javascript
利用js对象弹出一个层
Mar 26 Javascript
JavaScript URL参数读取改进版
Jan 16 Javascript
Javascript进制转换实例分析
May 14 Javascript
jquery实现九宫格大转盘抽奖
Nov 13 Javascript
js HTML5上传示例代码完整版
Oct 10 Javascript
JS实现的表头列头固定页面功能示例
Jan 10 Javascript
Bootstrap 填充Json数据的实例代码
Jan 11 Javascript
.net MVC+Bootstrap下使用localResizeIMG上传图片
Apr 21 Javascript
vue音乐播放器插件vue-aplayer的配置及其使用实例详解
Jul 10 Javascript
ionic2屏幕适配实现适配手机、平板等设备的示例代码
Aug 11 Javascript
微信小程序wx.request的简单封装
Nov 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
PHP跨时区(UTC时间)应用解决方案
2013/01/11 PHP
PHP中iconv函数转码时截断字符问题的解决方法
2015/01/21 PHP
php+mysql+jquery实现日历签到功能
2017/02/27 PHP
PHP中使用mpdf 导出PDF文件的实现方法
2018/10/22 PHP
很酷的javascript loading效果代码
2008/06/18 Javascript
Jquery AutoComplete自动完成 的使用方法实例
2010/03/19 Javascript
javascript针对DOM的应用分析(四)
2012/04/15 Javascript
Js 获取Gridview选中行的内容操作步骤
2013/02/05 Javascript
jquery特效 幻灯片效果示例代码
2013/07/16 Javascript
简体中文转换繁体中文(实现代码)
2013/12/25 Javascript
对比分析AngularJS中的$http.post与jQuery.post的区别
2015/02/27 Javascript
jQuery操作表单常用控件方法小结
2015/03/23 Javascript
JavaScript自动点击链接 防止绕过浏览器访问的方法
2017/01/19 Javascript
Jquery树插件zTree实现菜单树
2017/01/24 Javascript
Webpack+Vue如何导入Jquery和Jquery的第三方插件
2017/02/20 Javascript
从零学Python之入门(四)运算
2014/05/27 Python
PyMongo安装使用笔记
2015/04/27 Python
详解Python中的静态方法与类成员方法
2017/02/28 Python
python中的随机函数小结
2018/01/27 Python
python使用自定义钉钉机器人的示例代码
2020/06/24 Python
python中random模块详解
2021/03/01 Python
HTML5 语音搜索(淘宝店语音搜素)
2013/01/03 HTML / CSS
 Alo Yoga官网:购买瑜伽服装
2018/06/17 全球购物
微软加拿大官方网站:Microsoft Canada
2019/04/28 全球购物
Hobbs官方网站:英国奢华女性时尚服装
2020/02/22 全球购物
测绘工程本科生求职信
2013/10/10 职场文书
自考自我鉴定范文
2013/10/30 职场文书
安全大检查反思材料
2014/01/31 职场文书
三八妇女节活动主持词
2014/03/17 职场文书
迎新晚会主持词
2014/03/24 职场文书
社会学专业求职信
2014/07/17 职场文书
银行授权委托书范本
2014/10/04 职场文书
2015年党员个人自我评价
2015/03/03 职场文书
音乐教师求职信范文
2015/03/20 职场文书
如何在Mac上通过docker配置PHP开发环境
2021/05/29 PHP
斗罗大陆八大特殊魂兽,龙族始祖排榜首,第五最残忍(翠魔鸟)
2022/03/18 国漫