python中的递归问题,求圆周率

python中的递归问题,求圆周率

<span>python中的递归问题,求圆周率</span>

以上面一个公式为例:

import numpy as np
def getPi(n):
    if n == 0:
        return np.power(-1,n)*(1.0/(2*n+1))
    else:
        return np.power(-1,n)*(1.0/(2*n+1))+getPi(n-1)
    
print 4*getPi(100)

  

 

可以通过上面一个递归实现。

参考

特点:

①递归就是在过程或者函数里调用自身。

②在使用递归策略时,必须有一个明确的递归条件,称为递归出口。

③递归算法解题通常显得很简洁,但递归算法解题的效率较低。所以一般不倡导使用递归算法设计程序。

④在递归调用的过程当中系统的每一层的返回点、局部变量等开辟了栈来存储。递归函数次数过多容易造成栈溢出等。

   所以一般不倡导用递归算法设计程序。

要求:

递归算法所体现的”重复”一般有三个条件:

①每次在调用规模上都有所缩小(通常是减半)。

②相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入)。

③在问题的规模极小时必须用直接接触解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条件),

   无条件的递归调用将会成为死循环而不能正常结束。

 

每当你调用一个函数,在这个函数执行前都会将之前的代码地址(也就是调用点)入栈,等被调用的函数执行完将地址出栈,程序根据这个数据返回调用点。
若递归调用次数太多,就会只入栈不出栈,于是堆栈就被压爆了,此为栈溢出。

 

python中的解决办法:

1、人为设置递归深度

import sys
sys.setrecursionlimit(1000000) #括号中的值为递归深度

  事实上并不能完全解决,太多还是会程序崩溃的。

 

2、所谓的尾递归

import numpy as np

def getPi(n,m):
    if n == 0:
        return m+np.power(-1,n)*(1.0/(2*n+1))
    else:
        return getPi(n-1,m+np.power(-1,n)*(1.0/(2*n+1)))
    
print 4*getPi(100,0)

  尾递归参考:https://www.cnblogs.com/hello–the-world/archive/2012/07/19/2599003.html

尾递归的写法就是将操作的值作为参数传递,事实上,python并不支持尾递归的优化!而且对递归的次数有限制,当递归深度超过1000时,会抛出异常。

故对于继续研究突破递归次数的话,虽然有高手找到解决办法,并没有太大意义。

 

3、利用迭代的方式,而不是使用递归(譬如,reduce)

import numpy as np

s = reduce(lambda x,n:x+np.power(-1,n)*(1.0/(2*n+1)),[np.power(-1,0)*(1.0/(2*0+1))]+range(1,100000))
print 4*s

s = reduce(lambda x,n:x+np.power(-1,n)*(1.0/(2*n+1)) if x>0 else np.power(-1,x)*(1.0/(2*x+1))+np.power(-1,n)*(1.0/(2*n+1)),\
          range(0,100000))
print 4*s

  可以看到,利用reduce函数是处理这类问题的比较好的办法。用一句话总结:

                                                  普通程序员用迭代,天才程序员用递归!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119477.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java基本输入语句_java键盘输入语句

    java基本输入语句_java键盘输入语句在Java中进行输入时,最常用的两种输入方式为:1.使用ScannerScanner使用步骤:导入包importjava.util.Scanner;//导包的动作必须出现在类定义的上方创建对象//newScanner(System.in)为固定格式,不可以改变Scannersc=newScanner(System.in); 接收数据inti=sc.nextInt(); //这里使用的为int型,如果改变,则需要改变sc.nextInt();

    2022年9月15日
    3
  • Docker卸载_docker创建容器

    Docker卸载_docker创建容器Linux服务器Docker卸载某个镜像:首先输入命令dockerimages查看当前docker下有多少镜像:1[root@iZwz9a191mdam4di3dozk3Z~]#dockerimages2REPOSITORYTAGIMAGEIDCREATEDSIZE3mysql…

    2025年10月4日
    5
  • 初始化任务Bootstrapper

    初始化任务Bootstrapper每个应用程序都需要在启动的时候做些初始化任务,在退出的时候做些清理工作,这类任务被归为Bootstrapper,在codeplex上的开源项目,详见http://bootstrapper.codeplex.com/帮助我们来完成以下的任务。1、在需要的时候,我们可以把实现和接口进行分离,实现使用依赖注入(不一定要项目引用,只需要文件夹下有实现的DLL…

    2022年7月20日
    12
  • c语言中按位异或运算,^按位异或运算符「建议收藏」

    c语言中按位异或运算,^按位异或运算符「建议收藏」^表示按位异或运算符,顾名思义,相异,即不同则为1,反之为0例如15和16进行异或运算,运算过程如下:15000000000000000000000000000011111600000000000000000000000000010000^——————————————000000000000…

    2022年5月3日
    38
  • 模拟电子技术基础 思维导图

    模拟电子技术基础 思维导图模拟电子技术基础-思维导图参考孙肖子等编著.——北京:高等教育出版社,2012.12稍后将细致介绍每一章节的内容及重点应用!!!

    2022年6月20日
    40
  • python分组聚合_python爬虫标签

    python分组聚合_python爬虫标签由于某些原因,回归和分类问题总会引起机器学习领域的大部分关注。多标签分类在数据科学中是一个比较令人头疼的问题。在这篇文章中,我将给你一个直观的解释,说明什么是多标签分类,以及如何解决这个问题。1.多标签分类是什么?让我们来看看下面的图片。如果我问你这幅图中有一栋房子,你会怎样回答?选项为“Yes”或“No”。或者这样问,所有的东西(或标签)与这幅图有什么关系?在这些类型的问题中,我们有一组目标变…

    2025年7月22日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号