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复制插件Zero使用介绍
Mar 19 Javascript
基于jquery实现的文字向上跑动类似跑马灯的效果
Jun 17 Javascript
Javascript 中创建自定义对象的方法汇总
Dec 04 Javascript
每天一篇javascript学习小结(RegExp对象)
Nov 17 Javascript
原生js和jQuery实现淡入淡出轮播效果
Dec 25 Javascript
jquery ztree实现模糊搜索功能
Feb 25 Javascript
使用jquery提交form表单并自定义action的方法
May 25 Javascript
HTML5基于Tomcat 7.0实现WebSocket连接并实现简单的实时聊天
Oct 31 Javascript
如何清除IE10+ input X 文本框的叉叉和密码输入框的眼睛图标
Dec 21 Javascript
详解js的六大数据类型
Dec 27 Javascript
JS对象与json字符串相互转换实现方法示例
Jun 14 Javascript
vue把输入框的内容添加到页面的实例讲解
Nov 11 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 STRING 陷阱原理说明
2010/07/24 PHP
探讨php中header的用法详解
2013/06/07 PHP
如何用php获取程序执行的时间
2013/06/09 PHP
PHP 转义使用详解
2013/07/15 PHP
PHP Streams(流)详细介绍及使用
2015/05/12 PHP
ModelDialog JavaScript模态对话框类代码
2011/04/17 Javascript
简单的ajax连接库分享(不用jquery的ajax)
2014/01/19 Javascript
javascript中的正则表达式使用指南
2015/03/01 Javascript
JS模仿手机端九宫格登录功能实现代码
2016/04/28 Javascript
基于three.js编写的一个项目类示例代码
2018/01/05 Javascript
JavaScript解决浮点数计算不准确问题的方法分析
2018/07/09 Javascript
浅谈Vue.js路由管理器 Vue Router
2018/08/16 Javascript
Vue 实现拖动滑块验证功能(只有css+js没有后台验证步骤)
2018/08/24 Javascript
vue mounted 调用两次的完美解决办法
2018/10/29 Javascript
浅谈Vue数据响应思路之数组
2018/11/06 Javascript
js实现web调用摄像头 js截取视频画面
2019/04/21 Javascript
详解VUE前端按钮权限控制
2019/04/26 Javascript
解决Vue项目打包后打开index.html页面显示空白以及图片路径错误的问题
2019/10/25 Javascript
Python2中的raw_input() 与 input()
2015/06/12 Python
Python验证码识别的方法
2015/07/10 Python
python中的随机函数random的用法示例
2018/01/27 Python
python 多线程串行和并行的实例
2019/02/22 Python
Tensorflow中的降维函数tf.reduce_*使用总结
2020/04/20 Python
python实现简单的五子棋游戏
2020/09/01 Python
Django Auth用户认证组件实现代码
2020/10/13 Python
HTML5本地存储之Database Storage应用介绍
2013/01/06 HTML / CSS
杭州龙健科技笔试题.net部分笔试题
2016/01/24 面试题
物业管理大学生个人的自我评价
2013/10/10 职场文书
采购员的工作职责
2013/12/26 职场文书
安全负责人任命书
2014/06/06 职场文书
空气环保标语
2014/06/12 职场文书
搞笑老公保证书
2015/02/26 职场文书
见习期个人总结
2015/03/05 职场文书
2015年消防工作总结
2015/04/24 职场文书
贴吧吧主申请感言
2015/08/03 职场文书
Python中requests做接口测试的方法
2021/05/30 Python