递归函数,通过把一个大而复杂问题简化为许多但规模较小的问题,以同一个相似模式来计算,降低了解题的难度;通过调用自身函数,极大地减少了函数代码量的优点而为开发者喜爱。但因其不断调用自身函数开辟新栈,且大量传入同样参数,得到同样的结果,重复同一行为,也会浪费大量的内存。

以经典问题,斐波那契数列为例:

斐波那契数列指的是这样一个数列: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,求其第N项的值。

对数列进行分析,我们发现,从自三项开始,第N项的值就等于其前两项之和,即第N-1和第N-2项的和。所以我们可以这样写func(n)=func(n-1)+func(n-2)

代码如下:

 function fibonacci(n){
if((n==0)||(n==1)){
return n;
}else{
  return fibonacci(n-1)+fibonacci(n-2);//调用自身函数实现递归
}
}

分析代码我们发现,计算第N项的值总要计算第0项或第1项等较小的项的值,且会进行多次运算,结果相同。在此函数内,其边界项(0、1项)简便,若是进行边界项复杂的函数,内存会大量浪费。

memoization的思想是通过定义一个数组,用来存放计算过的数据,在需要的时候直接从数组中取出,而不必再次计算,从而省去大量不必要的动作。

以下是JS实现方式:

var fibonacci=function(n){
var cache=[];//定义一个空数组用来存放计算好的数据
  if((n==0)||(n==1)){
    return n;
  }else{
    cache[n-1]=cache[n-1]||fibonacci(n-1);//应用||或运算符“短路”的特性,若在数组中找到其值,则直接使用数组内的值,若没有,再进行计算,并将值存入数组
    cache[n-2]=cache[n-2]||fibonacci(n-2);
    return cache[n-1]+cache[n-2];//返回数组中的值
  }
}

由上可以看出,在计算过一次后,数据被存入数组,再次调用时便会优先找到数组内的值而免于大量计算,从而提升效率。

以下是PHP实现(其实差不多。。。)

function fibonacci($n){
  $cache=[];
  if(($n==0)||($n==1)){
    return $n;
  }else{
    cacehe[$n-1]=cache[$n-1]||fibonacci($n-1);
    cacehe[$n-2]=cache[$n-2]||fibonacci($n-2);
    return cache[$n-1]+cache[$n-2];
  }
}

开始总结笔记了,如有错误,请各位不吝指正,谢谢。

用memoization优化递归算法[JS/PHP实现]的更多相关文章

  1. JavaScript性能优化篇js优化

    JavaScript性能优化篇js优化   随着Ajax越来越普遍,Ajax引用的规模越来越大,Javascript代码的性能越来越显得重要,我想这就是一个很典型的例子,上面那段代码因为会被频繁使用, ...

  2. js Memoization 优化运行速度

    项目中需要用到 大计算量 耗时的js运算. Memoize 是一个优化方法 ,对耗时的递归运算,漫长的查找运算的结果进行缓存,使运行时间最小化 原理是缓存先前的结果计算值从而可以避免需要重新计算   ...

  3. Web性能优化-合并js与css,减少请求

    Web性能优化已经是老生常谈的话题了, 不过笔者也一直没放在心上,主要的原因还是项目的用户量以及页面中的js,css文件就那几个,感觉没什么优化的.人总要进步的嘛,最近在被angularjs吸引着,也 ...

  4. 页面性能优化-原生JS实现图片懒加载

    在项目开发中,我们往往会遇到一个页面需要加载很多图片的情况.我们可以一次性加载全部的图片,但是考虑到用户有可能只浏览部分图片.所以我们需要对图片加载进行优化,只加载浏览器窗口内的图片,当用户滚动时,再 ...

  5. web性能优化之js图片懒加载

    html <div class="container"> <ul> <li> <div id="first" clas ...

  6. 一种优化递归算法的方法(javascript)

    看书的时候看到了这个比较酷的方法,分享一下. 一.问题描述:代码如下,我们以计算阶乘(factorial)为例,当重复调用factorial(9),factorial(8),factorial(7)的 ...

  7. 优化:js 逻辑运算符优化

    运算符的代码优化,可以精简代码,提高代码可读性 下面主要讨论下逻辑运算符与 &&, 或||. 示例: 假设对成长速度显示规定如下: 成长速度为5显示1个箭头: 成长速度为10显示2个箭 ...

  8. 前端用户体验优化: JS & CSS 各类效果代码段

    前言 不定时更新 在线预览 https://zzyper.github.io/opti... 在线预览的源码 https://github.com/zzyper/opt... 部分内容仅兼容webki ...

  9. 【前端优化】js图片懒加载及优化

    一.前言 为啥要对图片使用懒加载?我们首先来聊聊这个问题,对于页面来说架子啊速度影响着最大的就是图片,一张普通的图片可以达到4-5M的大小,而代码压缩也就只有几十KB.当页面图片过多的时候,页面加载速 ...

随机推荐

  1. 三分 --- POJ 3301 Texas Trip

    Texas Trip Problem's Link:   http://poj.org/problem?id=3301 Mean: 给定n(n <= 30)个点,求出包含这些点的面积最小的正方形 ...

  2. C#客户端Redis服务器的分布式缓存

    介绍 在这篇文章中,我想介绍我知道的一种最紧凑的安装和配置Redis服务器的方式.另外,我想简短地概述一下在.NET / C#客户端下Redis hash(哈希类型)和list(链表)的使用. 在这篇 ...

  3. 使用innerHTML获取HTML代码时,HTML标记属性的双引号好多都消失不见了,原来是属性值中包含空格才会保留双引号

    最近搞的一个项目中所使用的方式比较奇怪,用Label显示HTML内容,然后不断地使用JS把Label的innerHTML复制到TextBox中. 但是,昨天发现了一个问题,获取元素值的时候,有时候正常 ...

  4. .net开发微信公众平台

    一.说明:公众平台信息接口为开发者提供了一种新的消息处理方式,只有申请成为开发者后,你才能使用公众平台的开发功能,在这里你需要填写一个URL和一个Token,这两项信息也需要你拥有自己的服务器(外网服 ...

  5. webservice 原理

    webservice 原理1.soap协议,其实就是用http协议来传输xml格式的数据,可以post,get.一般有post.2.服务端有:本地程序代码(也不是dll)和xml格式的文件用来描述dl ...

  6. 织梦CMS的MVC体系

    13年无意中翻看DedeCMS的代码,发现DedeCMS中是有了一个基本MVC框架的,在现有的版本中,主要是应用到了ask.book等模块上. 织梦这个东西,里面很多设计思想是非常优秀的,但整体代码的 ...

  7. 基于 ANSIBLE 自动化运维实践

    摘要:运维这个话题很痛苦,你做任何的产品都离不开运维.不管你用什么语言.什么平台.什么技术,真正能够决定你产品成熟度的很有可能就是你运维的能力.取自 云巴 CEO 张虎在 ECUG 大会上的分享. 云 ...

  8. struts2中valueStack,stackContext以及actionContext的关系

    一,首先给出三者的定义 1.valueStack: 里面存放的是Action类中通过set方法设置的属性值(表单传过来的值等),由OGNL框架实现; 2.stackContext: 也是用来存值的,s ...

  9. Python迭代器:捕获Generator的返回值

    但是用for循环调用generator时,发现拿不到generator的return语句的返回值.如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的v ...

  10. 通过NameValuePairsValueProvider对象来获取指定前缀的Key

    using System; using System.Collections.Generic; using System.Linq; using System.Web.Http.ValueProvid ...