• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >编程问答 > 关于尾递归的问题

关于尾递归的问题

作者:佚名 字体:[增加 减小] 来源:互联网 时间:2017-06-07

佚名通过本文主要向大家介绍了尾递归,尾递归优化,什么是尾递归,python 尾递归,logo尾递归等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题:关于尾递归的问题
描述:

引子

设 m、n 为正整数,

  • 当乘积 mn 等于 0 时,函数f(m, n) 等于 m + n + 1,
  • 否则 f(m, n) 等于 f(m - 1, f(m, n - 1))。

下面是上述问题的一段简单代码(Javascript)

javascriptfunction f(m, n) {
    if (m * n == 0) {
        return m + n + 1
    }
    return f(m - 1, f(m , n - 1))
}

console.log(f(2, 1)) // 5

疑惑

摘自电子书ECMA6 入门中的 尾递归 的定义:

函数调用自身,称为递归。如果尾调用自身,就称为尾递归。

引子代码中的函数f是return了自身,但是其第二个参数又调用f,那么在这种情况下,

  1. 函数f算不算是尾递归呢?
  2. 如果f不是尾递归,又如何改成尾递归(如能改)?


解决方案1:

當且僅當尾調用自身。

return f(m - 1, f(m , n - 1)) 中的 f(m , n - 1) 顯然不是尾調用。

解决方案2:

题目里面的不是尾递归,因为函数的最后实际相当于如下形式,很显然不是尾递归。

var r = f(m , n - 1);
return f(m - 1, r);

而把这个函数改造成尾递归是可行的,实际上任何函数都可以改造成尾递归形式。

function f(m, n) {
    function cps(m, n, cb) {
        if (m*n == 0) {
            cb(m + n + 1)
            return
        }

        cps(m, n - 1, function(r) {
            cps(m - 1, r, cb)
        })
    }

    var result
    cps(m, n, function(r) {
        result = r
    })
    return result
}

不过可惜的是,javascript 不支持尾递归优化,改成这种形式之后反而因为增加了中间层次导致挂的更快,所以这个变换在 javascript 里面也只有理论意义而已。

解决方案3:

这个无法转换成尾递归或者循环,实际上也无法在递归里缓存用到的值,实际上m稍微一大就会导致f(m,n)的结果极大,很快就超出long double精度了。

事实上在JS里,f(3,1022)就已经超出了JS的最大数Infinity,f(3,1021)的结果等于 1.5729814930045264e+308,
f(4,3)更是天文数字,值为 7*2^(2.358995333375681e+67) - 3,试想一下2的这么多次方就觉得吓尿了,远超过Infinity。

f(5,1)=f(4,f(5,0))=f(4,6)更是远超过f(4,3),所以后面都不用计算了,全是Infinity

用JS实现楼主的题目,我们可以总结出通项式来

javascriptfunction f(m,n){
    if(m===0 || n===0) return m+n+1;
    if(m===1){
        return n+2;
    }else if(m===2){
        return 2*n+3;
    }else if(m===3){
        return 7*Math.pow(2,n)-3;
    }else if(m===4){
         // 递归一下f3的通项式
         function f4(n){
            var f3=function(x){return 7*Math.pow(2,x)-3}
            if(n==0)return 5;
             return f3(f4(n-1));
        }
        return f4(n);
    }
    return Infinity;
}

速度当然是非常快的,楼主可以用自己递归的实现和我上面的实现执行一下f(2,5600)试试,差别相当大,而且递归的实现,如果用f(2,6000)就会爆栈,call stack太多。

递归算法,递归调用,递归函数,java递归,递归的例子,php递归,c#递归,递归思想,递归求和,递归查询,递归排序,递归回溯,js递归,阶乘递归,尾递

看一下速度

递归算法,递归调用,递归函数,java递归,递归的例子,php递归,c#递归,递归思想,递归求和,递归查询,递归排序,递归回溯,js递归,阶乘递归,尾递

还有递归根本执行不了的这个

递归算法,递归调用,递归函数,java递归,递归的例子,php递归,c#递归,递归思想,递归求和,递归查询,递归排序,递归回溯,js递归,阶乘递归,尾递

解决方案4:

不是尾递归。。 f(m , n - 1)执行结束后需要向上层返回执行结果,也就是把结果给f(m - 1, f(m, n - 1))然后继续递归。。那么程序运行时必然会保存f函数上一层的状态,所以这跟普通递归一样的


分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 关于尾递归的问题

相关文章

  • 2017-06-07 在javascript中如何正则匹配<>外面的关键字并替换?
  • 2017-06-07 python!requests!post!的时候遇到的问题
  • 2017-06-07 JBOSS的URL如何不区分大小写
  • 2017-06-07 深圳市安居型商品房建设和管理暂行办法求个商家和商品对应关系的算法
  • 2017-06-07 JavaScriptStringfromCharCode的charCode是什么?
  • 2017-06-07 编程出现2个警告不知道出在哪求指点小白求解
  • 2017-06-07 七牛云使用callbackUrl进行回写无法访问服务器
  • 2017-06-07 python调用C写的dll
  • 2017-06-07 建议七牛帮助完善开源软件FileConveyor
  • 2017-06-07 谁懂JSP,求教

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 七牛图片外链地址
    • 在多个网格A寻路
    • 能获得音频、视频文件的元数据吗?
    • (python)linux下用wsgifunc运行webpy该如何修改代码
    • [需求建议]有哪个大神可以为这个现代论坛程序做个云存储插件
    • python数列问题?
    • 基于七牛用python实现分片上传创建文件报错701
    • 你猜你猜你猜猜猜张杰如何理解”猜字游戏“中的这句话?
    • intelx86里以下机器码的执行快慢
    • (python)Scrapyrequest增长太快,有什么好方法消化它们?

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有