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

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

斐波那契数列指的是这样一个数列: 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. CSS3魔法堂:背景渐变(Gradient)

    一.前言 很久之前就了解过CSS3的线性渐变(Linear-Gradient),这段时间决定进一步认知这一特性,以下笔记以便日后查阅. 二.CSS3的各种背景渐变   1. 线性渐变 示例——七彩虹 ...

  2. 软件工程——sprint 1回顾总结

    主题:“我们在本次sprint中做了什么?接下来的打算?” sprint总结:在本次sprint里,这是我们团队的成员们第一次开始以团队的形式进行一次团队项目开发,早在第一次团队会议之时,我们便因团队 ...

  3. 无意中在sql日志中发现如下内容,

    日期,源,严重性,消息01/06/2015 09:06:13,登录,未知,Length specified in network packet payload did not match number ...

  4. [CLR via C#]19. 可空值类型

    我们知道,一个值类型的变量永远不可能为null.它总是包含值类型本身.遗憾的是,这在某些情况下会成为问题.例如,设计一个数据库时,可将一个列定义成为一个32位的整数,并映射到FCL的Int32数据类型 ...

  5. Js中各类型数据到bool的转换

    在返回Json字符串给前台时遇到的问题,返回的bool数据总是为TRUE 特意查了一下,发现了Js中各类数据转换到bool型是的结果. 希望能给遇到同样问题的人一点帮助.  数据类型  转换为bool ...

  6. 怎样用C#代码知道是否已连接网络

    有时,上传数据和下载数据都需要用到网络,但是不知道程序是否已连接到网络,下面是简单测试是否已连接网络的小功能 1.在winform窗体上添加一个按钮和多选框

  7. javascript中怎样验证密码是否含有特殊符号、数字、大小写字母,长度是否大于6小于12

    今天在温习了一下以前学过的知识,一般常用验证密码是通过正则表达式或是通过ASCII 一.用AscII码来验证

  8. 并发式IO的解决方案:多路非阻塞式IO、多路复用、异步IO

    在Linux应用编程中的并发式IO的三种解决方案是: (1) 多路非阻塞式IO (2) 多路复用 (3) 异步IO 以下代码将以操作鼠标和键盘为实例来演示. 1. 多路非阻塞式IO 多路非阻塞式IO访 ...

  9. ThinkPHP去掉URL中的index.php

    我的环境是apache+ubuntu 1,先确认你有没mod_rewrite.so模块 /usr/lib/apache2/modules/mod_rewrite.so 然后在httpd.conf最后一 ...

  10. 类库LinqToExcel的介绍

            LinqToExcel是一个.net framework平台下开源项目,它主要实现了LINQ的语法查询Excel电子表格.类型之前的LINQToXXX如果你是LINQ语法糖爱好者那最适 ...