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 相关文章推荐
记录几个javascript有关的小细节
Apr 02 Javascript
jQuery toggle()设置CSS样式
Nov 05 Javascript
document.documentElement的一些使用技巧
Apr 18 Javascript
一个通过script自定义属性传递配置参数的方法
Sep 15 Javascript
jQuery中innerHeight()方法用法实例
Jan 19 Javascript
Jquery搜索父元素操作方法
Feb 10 Javascript
jQuery实现自动与手动切换的滚动新闻特效代码分享
Aug 27 Javascript
js鼠标经过tab选项卡时实现切换延迟
Mar 24 Javascript
Vue制作Todo List网页
Apr 26 Javascript
Element-ui中元素滚动时el-option超出元素区域的问题
May 30 Javascript
vue中的面包屑导航组件实例代码
Jul 01 Javascript
Vue实现点击显示不同图片的效果
Aug 10 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
laravel 出现command not found问题的解决方案
2019/10/23 PHP
jQuery Tools tooltip使用说明
2012/07/14 Javascript
JQuery+CSS提示框实现思路及代码(纯手工打造)
2013/05/07 Javascript
JS字符串处理实例代码
2013/08/05 Javascript
JScript分割字符串示例代码
2013/09/04 Javascript
JS+flash实现chrome和ie浏览器下同时可以复制粘贴
2013/09/22 Javascript
nodejs文件操作模块FS(File System)常用函数简明总结
2014/06/05 NodeJs
JavaScript实现将数组数据添加到Select下拉框的方法
2015/08/21 Javascript
jQuery实现的背景动态变化导航菜单效果
2015/08/24 Javascript
AngualrJS中每次$http请求时的一个遮罩层Directive
2016/01/26 Javascript
js和jq使用submit方法无法提交表单的快速解决方法
2016/05/17 Javascript
JCrop+ajaxUpload 图像切割上传的实例代码
2016/07/20 Javascript
你有必要知道的10个JavaScript难点
2017/07/25 Javascript
babel之配置文件.babelrc入门详解
2018/02/22 Javascript
JavaScript实现京东放大镜效果
2019/12/03 Javascript
js 动态校验开始结束时间的实现代码
2020/05/25 Javascript
JavaScript实现世界各地时间显示
2020/09/07 Javascript
Nest.js散列与加密实例详解
2021/02/24 Javascript
[01:52]DOTA2完美大师赛Vega战队趣味视频——kpii老师小课堂
2017/11/25 DOTA
Python对列表中的各项进行关联详解
2017/08/15 Python
python 统计列表中不同元素的数量方法
2018/06/29 Python
python 直接赋值和copy的区别详解
2019/08/07 Python
简单了解Python write writelines区别
2020/02/27 Python
如何完美的建立一个python项目
2020/10/09 Python
使用Html5、CSS实现文字阴影效果
2018/01/17 HTML / CSS
英国领先的杂志订阅网站:Magazine.co.uk
2018/01/25 全球购物
德尔福集团DELPHI的笔试题
2012/02/22 面试题
摄影助理岗位职责
2014/02/07 职场文书
公司委托书范本
2014/04/04 职场文书
战友聚会策划方案
2014/06/13 职场文书
爱护公共设施演讲稿
2014/09/13 职场文书
离职报告格式
2014/11/04 职场文书
倡议书作文
2015/01/19 职场文书
圣诞节开幕词
2015/01/29 职场文书
Golang之sync.Pool使用详解
2021/05/06 Golang
Python几种酷炫的进度条的方式
2022/04/11 Python