动态规划之使用备忘录来改进Javascript函数


Posted in Javascript onApril 07, 2022

前言;

动态规划已出现了十多年。根据维基百科,它既是一种数学优化方法,也是一种计算机编程方法。一个问题要真正应用动态规划,必须具有两个关键属性:最优结构和重叠子结构。本文不会细讲动态规划,而是将关注重叠子结构如何成为动态规划的关键属性之一。由于这关系到接下来的存储解决方案问题,所以对它的讨论非常重要。

本文将介绍什么是备忘录,备忘录对Javascript开发人员来说具有哪些价值,以及如何使用它来改进Javascript函数,从而对备忘录本身以及备忘录对优化应用程序的意义有一个深入了解。

在本文中,我们将讨论以下几个主题:

  • 什么是备忘录
  • 备忘录的主要概念
  • 函数使用备忘录和不用备忘录的比较
  • 备忘录的意义

什么是备忘录?

备忘录是缓存的一种形式,是一种方便进入和后续使用的值存储方法。备忘录是将已解决问题的结果记录下来,这样下次需要再次执行相同操作时,就不必重新计算了。不过,一个函数要使用备忘录,需要满足一定条件:它必须是引用透明的,即只有在调用函数的效果与用函数的返回值替换函数调用的效果完全相同的情况下才可以使用。

在Ruby、C++、Python等大多数编程语言中都有备忘录,这些语言中甚至有很多库可以简化。在本文中,我们将重点关注Javascript。编程语言或许不同,但其中的概念和思想是一致的。

备忘录的概念

备忘录需要理解以下两个概念:

1.引用透明

如果一个表达式可以在不改变程序行为的情况下被其对应的值替换(反之亦然),那么它就被称为引用透明。这要求表达式必须是纯的,即对于相同的输入,表达式的值必须相同,并且它的求值必须没有副作用。非引用透明的表达式称为引用不透明。

有了上面的解释,我们可以很快地把它和备忘录的行为联系起来,这个概念让我们可以写出一个带备忘录的函数。

2.查找表

查找表(LUT)是一个数组,它用更为简单的数组索引操作取代运行时计算。该过程被称为“直接寻址”,LUT与哈希表的不同之处在于它检索的是一个值。

比较函数使用备忘录和不用备忘录

以经典的斐波那契数列定义为例:

function Fibo(n) {  
   if (n < 2) {  
       return n;  
   }  
   return Fibo(n - 1) + Fibo(n - 2);  
} 

你可能预料到了,一旦开始使用大于20的数字,这个过程就会变得非常缓慢。而当你处理35左右的数字时,计算机估计也撑不住了。

解决方法是记录调用函数的返回结果

var IterMemoFib = function() {  
    var cache = [1, 1];  
    var fib = function(n) {  
        if (n >= cache.length) {  
            for (var i = cache.length; i <= n; i++) {  
               cache[i] = cache[i - 2] + cache[i - 1];  
           }  
       }  
       return cache[n];  
   }  

  return fib;  
}(); 

这部分有点麻烦,也不完全可读,或者你也可以让计算机来协助完成:

Fib = Fib.memoize();  

由于技术(浏览器安全策略)限制,备忘录函数的参数只能是数组或标量值,不能是对象。

下面的代码扩展了Function对象以添加备忘录功能。如果函数是一个方法,则可以将对象传递给memoize()。

Function.prototype.memoize = function () {  
var pad = {};  
var self = this;  
 var obj = arguments.length > 0 ? arguments[i] : null;  
  
 var memoizedFn = function () {  
 // Copy the arguments object into an array: allows it to be used as  
   // a cache key.  
   var args = [];  
   for (var i = 0; i < arguments.length; i++) {  
     args[i] = arguments[i];  
  }  
  
   // Evaluate the memoized function if it hasn't been evaluated with  
   // these arguments before.  
   if (!(args in pad)) {  
     pad[args] = self.apply(obj, arguments);  
  }  
  
   return pad[args];  
};  
   
 memoizedFn.unmemoize = function () {  
   return self;  
 };  
  
 return memoizedFn;  
};  
   
Function.prototype.unmemoize = function () {  
 alert("Attempt to unmemoize an unmemoized function.");  
 return null;  
};  

备忘录的意义

  • “记住”与某组特定输入相对应的结果
  • 备忘录降低了函数的时间成本以换取空间成本
  • 备忘录更不依赖机器

结论:什么是备忘录?

在本文中,我们讨论了备忘录以及它的两个主要概念:引用透明和查找表。此外,我们还探讨了它对Javascript代码的重要性,同时比较了未使用备忘录的代码和使用备忘录的代码之间的区别,并对缓存值所用的技术进行了一定了解。

到此这篇关于动态规划之使用备忘录来改进Javascript函数的文章就介绍到这了,更多相关备忘录改进Javascript函数内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
如何在Web页面上直接打开、编辑、创建Office文档
Mar 12 Javascript
仿校内登陆框,精美,给那些很厉害但是没有设计天才的程序员
Nov 24 Javascript
纯JS实现五子棋游戏兼容各浏览器(附源码)
Apr 24 Javascript
html5的自定义data-*属性和jquery的data()方法的使用示例
Aug 21 Javascript
JavaScript中的变量作用域介绍
Dec 31 Javascript
javascript创建函数的20种方式汇总
Jun 23 Javascript
jquery实现动画菜单的左右滚动、渐变及图形背景滚动等效果
Aug 25 Javascript
JavaScript中的定时器之Item23的合理使用
Oct 30 Javascript
jQuery获得字体颜色16位码的方法
Feb 20 Javascript
使用bootstrap validator的remote验证代码经验分享(推荐)
Sep 21 Javascript
NPM 安装cordova时警告:npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to
Dec 20 Javascript
javaScript实现鼠标在文字上悬浮时弹出悬浮层效果
Apr 12 Javascript
vue实现拖拽交换位置
Apr 07 #Vue.js
使用Ajax实现进度条的绘制
Vue.Draggable实现交换位置
vue-cli3.0修改打包后的文件名和文件地址,打包后本地运行报错解决
vue cli4中mockjs在dev环境和build环境的配置详情
简单聊聊TypeScript只读修饰符
Apr 06 #Javascript
关于JS中的作用域中的问题思考分享
You might like
phpmyadmin安装时提示:Warning: require_once(./libraries/common.inc.php)错误解决办法
2011/08/18 PHP
PHP 小心urldecode引发的SQL注入漏洞
2011/10/27 PHP
Destoon旺旺无法正常显示,点击提示“会员名不存在”的解决办法
2014/06/21 PHP
PHP 微信扫码支付源代码(推荐)
2016/11/03 PHP
在js中使用&quot;with&quot;语句中跨frame的变量引用问题
2007/03/08 Javascript
Javascript 的addEventListener()及attachEvent()区别分析
2009/05/21 Javascript
基于jquery实现图片相关操作(重绘、获取尺寸、调整大小、缩放)
2015/12/25 Javascript
angularjs表格ng-table使用备忘录
2016/03/09 Javascript
vue项目中api接口管理总结
2018/04/20 Javascript
webpack+vue-cli项目中引入外部非模块格式js的方法
2018/09/28 Javascript
操作按钮悬浮固定在微信小程序底部的实现代码
2019/08/02 Javascript
vue简单练习 桌面时钟的实现代码实例
2019/09/19 Javascript
JavaScript正则表达式验证登录实例
2020/03/18 Javascript
ES6学习教程之Promise用法详解
2020/11/22 Javascript
[01:02:48]2018DOTA2亚洲邀请赛 4.1 小组赛 A组 LGD vs OG
2018/04/02 DOTA
理解Python中的类与实例
2015/04/27 Python
在Python的Django框架中包装视图函数
2015/07/20 Python
Python选择网卡发包及接收数据包
2019/04/04 Python
浅谈Tensorflow 动态双向RNN的输出问题
2020/01/20 Python
python 日志模块logging的使用场景及示例
2021/01/04 Python
使用css实现android系统的loading加载动画
2019/07/25 HTML / CSS
html5 Canvas画图教程(1)—画图的基本常识
2013/01/09 HTML / CSS
露营世界:Camping World
2017/02/02 全球购物
英国香水店:The Perfume Shop
2017/03/27 全球购物
美国最大的旗帜经销商:Carrot-Top
2018/02/26 全球购物
什么是Assembly(程序集)
2014/09/14 面试题
大学班长的职责
2014/01/27 职场文书
总结表彰大会主持词
2014/03/26 职场文书
群众路线党课主持词
2014/04/01 职场文书
环保建议书500字
2014/05/14 职场文书
大学新闻系应届生求职信
2014/06/02 职场文书
小学生五年级大队长竞选发言稿
2014/09/12 职场文书
领导班子民主生活会整改措施(工商局)
2014/09/21 职场文书
Python访问Redis的详细操作
2021/06/26 Python
聊聊CSS粘性定位sticky案例解析
2022/06/01 HTML / CSS
VUE递归树形实现多级列表
2022/07/15 Vue.js