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 CheckBox全选方法代码附js checkbox全选反选代码
Jun 09 Javascript
ExtJs事件机制基本代码模型和流程解析
Oct 24 Javascript
JavaScript调用后台的三种方法实例
Oct 17 Javascript
Javascript单元测试框架QUnitjs详细介绍
May 08 Javascript
javascript通过元素id和name直接取得元素的方法
Apr 28 Javascript
JavaScript实现给定时间相加天数的方法
Jan 25 Javascript
AngularJS使用自定义指令替代ng-repeat的方法
Sep 17 Javascript
详解如何使用Vue2做服务端渲染
Mar 29 Javascript
JS仿QQ好友列表展开、收缩功能(第二篇)
Jul 07 Javascript
jQuery实现的事件绑定功能基本示例
Oct 11 jQuery
web前端vue filter 过滤器
Jan 12 Javascript
vue-cli设置css不生效的解决方法
Feb 07 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
打造计数器DIY三步曲(上)
2006/10/09 PHP
excellent!――ASCII Art(由目标图象生成ascii)
2007/02/20 PHP
PHP编程获取音频文件时长的方法【基于getid3类】
2017/04/20 PHP
什么是PHP7中的孤儿进程与僵尸进程
2019/04/14 PHP
PHP实现财务审核通过后返现金额到客户的功能
2019/07/04 PHP
javascript表单验证使用示例(javascript验证邮箱)
2014/01/07 Javascript
按下回车键指向下一个位置的一个函数代码
2014/03/10 Javascript
javascript对中文按照拼音排序代码
2014/08/20 Javascript
JavaScript中的cacheStorage使用详解
2015/07/29 Javascript
js判断鼠标位置是否在某个div中的方法
2016/02/26 Javascript
js手动播放图片实现图片轮播效果
2016/09/17 Javascript
js判断价格,必须为数字且不能为负数的实现方法
2016/10/07 Javascript
ES6新特性八:async函数用法实例详解
2017/04/21 Javascript
jQuery获取单选按钮radio选中值与去除所有radio选中状态的方法
2017/05/20 jQuery
JavaScript高阶函数_动力节点Java学院整理
2017/06/28 Javascript
js的函数的按值传递参数(实例讲解)
2017/11/16 Javascript
ng-zorro-antd 入门初体验
2018/12/03 Javascript
vue props 单项数据流实例分享
2020/02/16 Javascript
jQuery 添加元素和删除元素的方法
2020/07/15 jQuery
vue中destroyed方法的使用说明
2020/07/21 Javascript
jenkins自动构建发布vue项目的方法步骤
2021/01/04 Vue.js
[47:55]Ti4第二日主赛事败者组 NaVi vs EG 1
2014/07/20 DOTA
[03:36]2015国际邀请赛第二日现场精彩集锦
2015/08/06 DOTA
Django学习笔记之Class-Based-View
2017/02/15 Python
Python 调用Java实例详解
2017/06/02 Python
简单实现python收发邮件功能
2018/01/05 Python
python中requests和https使用简单示例
2018/01/18 Python
python删除文本中行数标签的方法
2018/05/31 Python
Python中调用其他程序的方式详解
2019/08/06 Python
python 利用jieba.analyse进行 关键词提取
2020/12/17 Python
2014年社区学雷锋活动总结
2014/03/09 职场文书
四年级学生评语大全
2014/04/21 职场文书
现实表现材料范文
2014/12/23 职场文书
2015年小学一年级班主任工作总结
2015/05/21 职场文书
小学大队干部竞选稿
2015/11/20 职场文书
《天净沙·秋思》教学反思三篇
2019/11/02 职场文书