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类库D
Oct 24 Javascript
JQuery的AJAX实现文件下载的小例子
May 15 Javascript
ECMAScript6的新特性箭头函数(Arrow Function)详细介绍
Jun 07 Javascript
jQuery控制网页打印指定区域的方法
Apr 07 Javascript
AngularJs动态加载模块和依赖注入详解
Jan 11 Javascript
用jQuery向div中添加Html文本内容的简单实现
Jul 13 Javascript
JS正则表达式之非捕获分组用法实例分析
Dec 28 Javascript
微信小程序实现滑动删除效果
May 19 Javascript
JavaScript实现为事件句柄绑定监听函数的方法分析
Nov 14 Javascript
vue使用element-ui的el-input监听不了回车事件的解决方法
Jan 12 Javascript
Bootstrap4如何定制自己的颜色和风格
Feb 26 Javascript
一篇文章看懂JavaScript中的回调
Jan 05 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 setcookie(name, value, expires, path, domain, secure) 参数详解
2013/06/28 PHP
PHP实现可自定义样式的分页类
2016/03/29 PHP
php中html_entity_decode实现HTML实体转义
2018/06/13 PHP
jQuery 获取URL参数的插件
2010/03/04 Javascript
千分位数字格式化(用逗号隔开 代码已做了修改 支持0-9位逗号隔开)的JS代码
2013/12/05 Javascript
JavaScript验证图片类型(扩展名)的函数分享
2014/05/05 Javascript
jQuery满屏焦点图左右滚动特效代码分享
2015/09/07 Javascript
javascript原生ajax写法分享
2016/04/10 Javascript
jQuery简单验证上传文件大小及类型的方法
2016/06/02 Javascript
如何解决hover在ie6中的兼容性问题
2016/12/15 Javascript
使用base64对图片的二进制进行编码并用ajax进行显示
2017/01/03 Javascript
原生JavaScript实现Ajax异步请求
2017/11/19 Javascript
vue中如何使用ztree
2018/02/06 Javascript
JS实现字符串翻转的方法分析
2018/08/31 Javascript
JavaScript工具库之Lodash详解
2019/06/15 Javascript
Ant Design Pro 之 ProTable使用操作
2020/10/31 Javascript
Vue使用鼠标在Canvas上绘制矩形
2020/12/24 Vue.js
[03:15]DOTA2-DPC中国联赛1月22日Recap集锦
2021/03/11 DOTA
python实现从字符串中找出字符1的位置以及个数的方法
2014/08/25 Python
pytorch 把MNIST数据集转换成图片和txt的方法
2018/05/20 Python
python实现画五角星和螺旋线的示例
2019/01/20 Python
python 整数越界问题详解
2019/06/27 Python
基于python tkinter的点名小程序功能的实例代码
2020/08/22 Python
巴西最大的体育用品商城:Netshoes巴西
2016/11/29 全球购物
自我评价优秀范文分享
2013/11/30 职场文书
一名老师的自我评价
2014/02/07 职场文书
土木工程师职业规划范文
2014/03/07 职场文书
大学新生入学教育方案
2014/05/16 职场文书
小学感恩节活动策划方案
2014/10/06 职场文书
2015年团委副书记工作总结
2015/07/23 职场文书
初一年级组工作总结
2015/08/12 职场文书
入党申请书怎么写?
2019/06/21 职场文书
80后创业总结的9条职场用人思想,记得收藏
2019/08/13 职场文书
关于企业的执行力标语大全
2020/01/06 职场文书
基于Nginx实现限制某IP短时间访问次数
2021/03/31 Servers
Python实现查询剪贴板自动匹配信息的思路详解
2021/07/09 Python