zoukankan      html  css  js  c++  java
  • 十三、递归及反射

    递归原理:递归要慎用
     
    斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368
    我们发现其规律为:后一个数等于它前面两个数之和
    需求:
    打印出如上所述序列:
    def func(arg1,arg2):
    if arg1 == 0:
    print (arg1, arg2)
    arg3 = arg1 + arg2
    print (arg3)
    func(arg2, arg3)
     
    func(0,1)
     
    递归的特点就是函数自己调用自己
    典型的应用就是通过递归实现简单计算功能:
    如下,需要计算这个的值
    a = '1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
    def handle(a):
    #获取只包含数字和+-*/
    #1-2*((60-30+( #我把它截断成三段
    #-40/5 = -8 #先把这个-40/5的值算出来
    #)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2)) #第三段
     
    #b = 新表达式
    handle(b)
     
    handle(a)
    =========================================================================================
    =========================================================================================
    =========================================================================================
    递归返回值:
    def func(arg1,arg2):
    if arg1 == 0:
    print (arg1, arg2)
    arg3 = arg1 + arg2
    print (arg3)
    if arg3 > 1000:
    return arg3
    func(arg2, arg3)
     
    result = func(0,1)
    print (result)
    我们会发现,它的结果居然是None,正确写法应该是这样:
    def func(arg1,arg2):
    if arg1 == 0:
    print (arg1, arg2)
    arg3 = arg1 + arg2
    print (arg3)
    if arg3 > 1000:
    return arg3
    return func(arg2, arg3)
     
    result = func(0,1)
    print (result)
    ==========================================================================================
    ==========================================================================================
    ==========================================================================================
    递归执行流程剖析:
    def n5():
    return 1500
    def n4():
    n5()
    def n3():
    n4()
    def n2():
    n3()
    def n1():
    n2()
     
    result = n1()
    print (result)
    问:result的值是多少?答:None
    因为n5的返回值是1500,但是是n4在调用n5,所以n4接收了1500这个值,但是n4接收了1500这个值不带表它返回了1500这个值,n4的返回值是None,类似往下走,一直到n1,返回值也是None
    问:如果我要n1的返回值是1500应该怎么做?
    答:
    def n5():
    return 1500
    def n4():
    return n5()
    def n3():
    return n4()
    def n2():
    return n3()
    def n1():
    return n2()
     
    result = n1()
    print (result)
    这样就等同于所有的返回值n1=n2=n3=n4=n5=1500
    对照递归的例子,是同理的
    =============================================================================
    =============================================================================
    递归的另外两个经典:阶乘和幂
    1.阶乘n*(n-1)*(n-2)......*1
    普通算法:
    def factorial(n):
    result = n
    for i in range(1,n):
    result *= 1
    return result
    递归算法:
    def factorial(n):
    if n == 1:
    return 1
    else:
    return n * factorial(n-1)
     
    2.幂运算power(2,3),即2的3次幂,2*2*2=8
    普通算法:
    def power(x,n):
    result = 1
    for i in range(n):
    result *= x
    return result
    递归算法:
    def power(x,n):
    if n == 0:
    return 1
    else:
    return x * power(x,n-1)
    ============================================================================
    =============================================================================
    反射:
    应用情景:假设我现在Myclass类下面有100个方法,我希望用户输入‘sayhi’我就调用sayhi方法,输入‘info’我就调用info方法,你如果通过if判断的话要写100个,而通过反射则简便的多,反射的应用相当广。
     
    class Myclass(object):
    def sayhi(self):
    print ('everybody I am sayhi')
    def info(self):
    print ('everybody I am info')
    def other(self):
    print ('everybody I am other')
     
    def run(): #注意这个run是和Myclass类处于同一级别
    print "running outside the class"
     
    m = Myclass() #实例化m这个对象
    user_input = 'sayhi' #这个就是用户的输入
     
     
    if hasattr(m,user_input): #意思是判断user_input是否在m里面,这里是‘sayhi’,在里面,往下走;如果是‘tt’,则会走 #else下面的语句user input not exitsts:
    func = getattr(m,user_input) #getattr是获取m这个类里面user_input的内存地址,然后赋值给func,在func()就执行
    func()
    else:
    print "user input not exitsts:",user_input
     
    setattr(m,user_input,run) #既然你输入的内容如‘tt'不存在,我就给它设置一个方法,方法名就叫tt,对应的执行的方法就是run这个函数
    f = getattr(m,user_input)
    f()
    print 'run test,but call run',m.tt()
     
    delattr(m.tt) #删除m.tt的方法,注意不能删除类里面的方法,如sayhi,info,other
     
     
  • 相关阅读:
    数据仓库基本概念
    收藏--关于命名规范、维度明细层及集市汇总层设计的思考
    Thinkphp6框架学习:有关数据库的基本操作
    算法第一章作业
    解决 Intellij IDEA Cannot Resolve Symbol ‘BASE Decoder’ 问题
    利用Kruskal算法求最小生成树解决聪明的猴子问题 -- 数据结构
    利用BFS解决拯救007问题 -- 数据结构
    列出连通集(DFS及BFS遍历图) -- 数据结构
    42行代码完成深入虎穴
    利用Tarjan算法解决(LCA)二叉搜索树的最近公共祖先问题——数据结构
  • 原文地址:https://www.cnblogs.com/steven9898/p/11329399.html
Copyright © 2011-2022 走看看