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 相关文章推荐
JQuery 简便实现页面元素数据验证功能
Mar 24 Javascript
关于JavaScript定义类和对象的几种方式
Nov 09 Javascript
JavaScript必知必会(六) delete in instanceof
Jun 08 Javascript
js替换字符串中所有指定的字符(实现代码)
Aug 17 Javascript
Vue.use源码学习小结
Jun 20 Javascript
详解如何从零开始搭建Express+Vue开发环境
Jul 17 Javascript
vue使用混入定义全局变量、函数、筛选器的实例代码
Jul 29 Javascript
vue-cli3配置与跨域处理方法
Aug 17 Javascript
JS代码检查工具ESLint介绍与使用方法
Feb 04 Javascript
JS如何把字符串转换成json
Feb 21 Javascript
深入解析微信小程序开发中遇到的几个小问题
Jul 11 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实现蜘蛛访问日志统计
2013/07/05 PHP
PHP封装的HttpClient类用法实例
2015/06/17 PHP
CodeIgniter实现从网站抓取图片并自动下载到文件夹里的方法
2015/06/17 PHP
PHP简单的MVC框架实现方法
2015/12/01 PHP
PHP环境搭建的详细步骤
2016/06/30 PHP
php微信高级接口调用方法(自定义菜单接口、客服接口、二维码)
2016/11/28 PHP
记录几个javascript有关的小细节
2007/04/02 Javascript
JAVASCRIPT  THIS详解 面向对象
2009/03/25 Javascript
精心挑选的15个jQuery下拉菜单制作教程
2012/06/15 Javascript
JS操作Cookies包括(读取添加与删除)
2012/12/26 Javascript
javascript 禁用IE工具栏,导航栏等等实现代码
2013/04/01 Javascript
JS.GetAllChild(element,deep,condition)使用介绍
2013/09/21 Javascript
javascript history对象(历史记录)使用方法(实现浏览器前进后退)
2014/01/07 Javascript
JS按回车键实现登录的方法
2014/08/25 Javascript
js检测iframe是否加载完成的方法
2015/11/26 Javascript
node.js从数据库获取数据
2016/05/08 Javascript
jQuery获取单击节点对象的方法
2016/06/02 Javascript
基于JS组件实现拖动滑块验证功能(代码分享)
2016/11/18 Javascript
微信小程序 省市区选择器实例详解(附源码下载)
2017/01/05 Javascript
angular directive的简单使用总结
2017/05/24 Javascript
Vue Ajax跨域请求实例详解
2017/06/20 Javascript
老生常谈Bootstrap媒体对象
2017/07/06 Javascript
简单实现js鼠标跟随效果
2020/08/02 Javascript
微信小程序使用map组件实现路线规划功能示例
2019/01/22 Javascript
js实现随机div颜色位置 类似满天星效果
2019/10/24 Javascript
[01:55]2014DOTA2国际邀请赛快报:国土生病 紧急去医院治疗
2014/07/10 DOTA
python 对多个csv文件分别进行处理的方法
2019/01/07 Python
pandas中的series数据类型详解
2019/07/06 Python
python判断是空的实例分享
2020/07/06 Python
巴西图书和电子产品购物网站:Saraiva
2017/06/07 全球购物
描述一下JVM加载class文件的原理机制
2013/12/08 面试题
数控技术与应用毕业生自荐信
2013/09/24 职场文书
演讲比赛获奖感言
2014/02/02 职场文书
新年联欢会主持词
2014/03/27 职场文书
租车协议书范本
2014/04/22 职场文书
群众路线对照检查材料思想汇报怎么写
2014/09/18 职场文书