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显示下拉列表框内全部元素的方法
Mar 31 Javascript
Js和JQuery获取鼠标指针坐标的实现代码分享
May 25 Javascript
简述JavaScript提交表单的方式 (Using JavaScript Submit Form)
Mar 18 Javascript
浅谈jQuery操作类数组的工具方法
Dec 23 Javascript
jQuery Ajax全解析
Feb 13 Javascript
Vue集成Iframe页面的方法示例
Dec 12 Javascript
微信小程序如何获取用户信息
Jan 26 Javascript
VSCode中如何利用d.ts文件进行js智能提示
Apr 13 Javascript
Vuejs学习笔记之使用指令v-model完成表单的数据双向绑定
Apr 29 Javascript
判断js数据类型的函数实例详解
May 23 Javascript
layui layer select 选择被遮挡的解决方法
Sep 21 Javascript
原生JavaScript实现轮播图
Jan 10 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
开源SNS系统-ThinkSNS
2008/05/18 PHP
探讨PHP删除文件夹的三种方法
2013/06/09 PHP
hadoop中一些常用的命令介绍
2013/06/19 PHP
php实现Mongodb自定义方式生成自增ID的方法
2015/03/23 PHP
php 流程控制switch的简单实例
2016/06/07 PHP
php实现生成code128条形码的方法详解
2017/07/19 PHP
IE 下的只读 innerHTML
2009/08/21 Javascript
修复IE9&amp;safari 的sort方法
2011/10/21 Javascript
js克隆对象、数组的常用方法介绍
2013/09/26 Javascript
Enter转换为Tab的小例子(兼容IE,Firefox)
2013/11/14 Javascript
js利用事件的阻止冒泡实现点击空白模态框的隐藏
2014/01/24 Javascript
js实现全国省份城市级联下拉菜单效果代码
2015/09/07 Javascript
跟我学习javascript的定时器
2015/11/19 Javascript
JavaScript 浏览器兼容性总结及常用浏览器兼容性分析
2016/03/30 Javascript
Nodejs Stream 数据流使用手册
2016/04/17 NodeJs
js鼠标按键事件和键盘按键事件用法实例汇总
2016/10/03 Javascript
微信小程序 数据交互与渲染实例详解
2017/01/21 Javascript
Vue中Table组件行内右键菜单实现方法(基于 vue + AntDesign)
2019/11/21 Javascript
在Vuex中Mutations修改状态操作
2020/07/24 Javascript
Vue组件通信$attrs、$listeners实现原理解析
2020/09/03 Javascript
Python Json模块中dumps、loads、dump、load函数介绍
2018/05/15 Python
解决Pycharm运行时找不到文件的问题
2018/10/29 Python
python 使用re.search()筛选后 选取部分结果的方法
2018/11/28 Python
python实现微信每日一句自动发送给喜欢的人
2019/04/29 Python
手动安装python3.6的操作过程详解
2020/01/13 Python
Python Socketserver实现FTP文件上传下载代码实例
2020/03/27 Python
解决python执行较大excel文件openpyxl慢问题
2020/05/15 Python
英国手机壳购买网站:Case Hut
2019/04/11 全球购物
业务经理岗位职责
2013/11/11 职场文书
邮政员工辞职信
2014/01/16 职场文书
小学生家长评语大全
2014/02/10 职场文书
党员干部作风建设思想汇报范文
2014/10/25 职场文书
2015年党日活动总结范文
2015/03/25 职场文书
2015年十月一日放假通知
2015/08/18 职场文书
某药房的新员工入职告知书!
2019/07/15 职场文书
Golang二维切片初始化的实现
2021/04/08 Golang