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里访问SharePoint列表数据的实现方法
May 22 Javascript
浅谈javascript的原型继承
Jul 25 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(三)情景对话中仿打字机输出文字
Jan 23 Javascript
jQuery 快速结束当前正在执行的动画
Nov 20 Javascript
快速解决jquery之get缓存问题的最简单方法介绍
Dec 19 Javascript
javascript for-in有序遍历json数据并探讨各个浏览器差异
Nov 30 Javascript
Vue.js报错Failed to resolve filter问题的解决方法
May 25 Javascript
BootStrap中Datetimepicker和uploadify插件应用实例小结
May 26 Javascript
深入理解JavaScript内置函数
Jun 03 Javascript
js实现导航栏中英文切换效果
Jan 16 Javascript
js定时器+简单的动画效果实例
Nov 10 Javascript
结合Vue控制字符和字节的显示个数的示例
May 17 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
投票管理程序
2006/10/09 PHP
php三元运算符知识汇总
2015/07/02 PHP
ThinkPHP框架实现定时执行任务的两种方法分析
2018/09/04 PHP
解决Laravel5.2 Auth认证退出失效的问题
2019/10/14 PHP
JavaScript CSS修改学习第六章 拖拽
2010/02/19 Javascript
原生js实现fadein 和 fadeout淡入淡出效果
2014/06/05 Javascript
JS实现兼容性好,自动置顶的淘宝悬浮工具栏效果
2015/09/18 Javascript
浅谈Jquery中Ajax异步请求中的async参数的作用
2016/06/06 Javascript
node.js发送邮件email的方法详解
2017/01/06 Javascript
Angular指令封装jQuery日期时间插件datetimepicker实现双向绑定示例
2017/01/22 Javascript
实例解析ES6 Proxy使用场景介绍
2018/01/08 Javascript
jQuery Dom元素操作技巧
2018/02/04 jQuery
Vue 使用formData方式向后台发送数据的实现
2019/04/14 Javascript
vue实现在v-html的html字符串中绑定事件
2019/10/28 Javascript
package.json各个属性说明详解
2020/03/11 Javascript
如何阻止移动端浏览器点击图片浏览
2020/08/29 Javascript
分享Python开发中要注意的十个小贴士
2016/08/30 Python
详谈python read readline readlines的区别
2017/09/22 Python
Python机器学习之决策树算法
2017/12/22 Python
python利用smtplib实现QQ邮箱发送邮件
2020/05/20 Python
Numpy中的mask的使用
2018/07/21 Python
Pycharm设置去除显示的波浪线方法
2018/10/28 Python
Python功能点实现:函数级/代码块级计时器
2019/01/02 Python
windows10下安装TensorFlow Object Detection API的步骤
2019/06/13 Python
python爬虫模拟浏览器的两种方法实例分析
2019/12/09 Python
PyTorch中反卷积的用法详解
2019/12/30 Python
python实现MySQL指定表增量同步数据到clickhouse的脚本
2021/02/26 Python
HTML5安全介绍之内容安全策略(CSP)简介
2012/07/10 HTML / CSS
.net面试题
2015/12/22 面试题
医科大学生毕业的自我评价分享
2013/11/12 职场文书
保护环境的建议书
2014/03/12 职场文书
新学期国旗下演讲稿
2014/05/08 职场文书
乐观自信演讲稿范文
2014/05/21 职场文书
用Python的绘图库(matplotlib)绘制小波能量谱
2021/04/17 Python
Python 制作自动化翻译工具
2021/04/25 Python
python如何利用cv2模块读取显示保存图片
2021/06/04 Python