首页 > 其他分享 >函数递归

函数递归

时间:2023-05-22 16:48:04浏览次数:37  
标签:salary f1 调用 函数 递归 薪水 1000

【一】函数递归

【1】函数递归介绍

  • 函数不仅可以嵌套定义,还可以嵌套调用

    • 即在调用一个函数的过程中,函数内部又调用另一个函数
    • 而函数的递归调用指的是在调用一个函数的过程中又直接或间接地调用该函数本身
  • 在调用f1的过程中,又调用f1

    • 这就是直接调用函数f1本身
def f1():
    print('from f1')
    f1()
f1()

  • 在调用f1的过程中,又调用f2
    • 而在调用f2的过程中又调用f1,这就是间接调用函数f1本身
def f1():
    print('from f1')
    f2()

def f2():
    print('from f2')
    f1()
    
f1()

  • 从上图可以看出,两种情况下的递归调用都是一个无限循环的过程
  • 但在python对函数的递归调用的深度做了限制,因而并不会像大家所想的那样进入无限循环,会抛出异常
    • 要避免出现这种情况,就必须让递归调用在满足某个特定条件下终止。
#1. 可以使用sys.getrecursionlimit()去查看递归深度,默认值为1000,虽然可以使用
sys.setrecursionlimit()去设定该值,但仍受限于主机操作系统栈大小的限制

#2. python不是一门函数式编程语言,无法对递归进行尾递归优化。

【二】回溯和递推

  • 下面我们用一个浅显的例子,为了让读者阐释递归的原理和使用:

  • 例4.5

    • 某公司四个员工坐在一起,问第四个人薪水,他说比第三个人多1000,问第三个人薪水,第他说比第二个人多1000,问第二个人薪水,他说比第一个人多1000,最后第一人说自己每月5000,请问第四个人的薪水是多少?
  • 思路解析:

    • 要知道第四个人的月薪,就必须知道第三个人的,第三个人的又取决于第二个人的,第二个人的又取决于第一个人的,而且每一个员工都比前一个多一千,数学表达式即:
salary(4)=salary(3)+1000
salary(3)=salary(2)+1000
salary(2)=salary(1)+1000
salary(1)=5000

总结为:
salary(n)=salary(n-1)+1000 (n>1)
salary(1)=5000 (n=1)
  • 很明显这是一个递归的过程

    • 可以将该过程分为两个阶段:
      • 回溯和递推。
  • 在回溯阶段

    • 要求第n个员工的薪水,需要回溯得到(n-1)个员工的薪水,以此类推,直到得到第一个员工的薪水,
    • 此时,salary(1)已知,因而不必再向前回溯了。然后进入递推阶段:
  • 从第一个员工的薪水可以推算出第二个员工的薪水(6000),从第二个员工的薪水可以推算出第三个员工的薪水(7000)

    • 以此类推,一直推算出第第四个员工的薪水(8000)为止,递归结束。需要注意的一点是,递归一定要有一个结束条件,这里n=1就是结束条件。

def salary(n):
    if n==1:
        return 5000
    return salary(n-1)+1000

s=salary(4)
print(s)

# 8000
  • 程序分析:
    • 在未满足n1的条件时,一直进行递归调用,即一直回溯,见图4.3的左半部分。而在满足n1的条件时,终止递归调用,即结束回溯,从而进入递推阶段,依次推导直到得到最终的结果。
    • 递归本质就是在做重复的事情,所以理论上递归可以解决的问题循环也都可以解决,只不过在某些情况下,使用递归会更容易实现,比如有一个嵌套多层的列表,要求打印出所有的元素,代码实现如下
items=[[1,2],3,[4,[5,[6,7]]]]
def foo(items):
    for i in items:
        if isinstance(i,list): #满足未遍历完items以及if判断成立的条件时,一直进行递归调用
            foo(i) 
        else:
            print(i,end=' ')
    
foo(items) #打印结果1 2 3 4 5 6 7
  • 使用递归,我们只需要分析出要重复执行的代码逻辑,
    • 然后提取进入下一次递归调用的条件或者说递归结束的条件即可,代码实现起来简洁清晰

标签:salary,f1,调用,函数,递归,薪水,1000
From: https://www.cnblogs.com/dream-ze/p/17421000.html

相关文章

  • strtok() 函数 2种方法的指针实现
    //Lvxin4-1strtok.cpp//strtok()函数的实现2种方法//下面的函数实现考虑一下3种极端情况://"-This,asamplestring"无行尾标志//"-This,asamplestring-"有一个行尾标志//"-This,asamplestring------”有多个行尾标志define_CRT_SECURE_NO_WARNING......
  • MySQL常用关键字和函数及部分关键字使用场景
    世间情动,不过盛夏白瓷梅子汤,碎冰碰壁当啷响。一,关键字使用顺序在使用SQL查询时,关键字的顺序并不是非常重要,SQL解释器可以根据查询的语法结构自动推断其执行顺序。但是,为了使查询更加易读,并且能够避免出现在结果中无法预期的重复数据,建议始终按照以下顺序使用关键字:1,SEL......
  • C++ inline 函数(转)
    (一)inline函数(摘自C++Primer的第三版)在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联。inlineintmin(intfirst,intsecend){/****/};     inline函数对编译器而言必须是可见的,以便它能够在调用点内展开该函数。与非inline函数不同的是,inline函数必......
  • 实验四 函数与异常编程处理
    实验任务1task1-1实验源码print(sum)sum=42print(sum)definc(n):sum=n+1print(sum)returnsumsum=inc(7)+inc(7)print(sum)实验截图问题:task1.py源码中,共有4处有python语句print(sum)(line1,line3,line7,line11)。这4处使用的标识......
  • 裴波那契数列的递归和动态规划算法
    裴波那契数列的递归和动态规划算法一、   概论通过对裴波那契数列的例子,分析了递归和动态规划算法的本质。并且说明了两种算法的区别。裴波那契数列:800年前,意大利的数学家斐波纳契出版了惊世之作《算盘书》。在《算盘书》里,他提出了著名的“兔子问题”:假定一对兔子每个月可......
  • 【PHP兴趣部落-09】递归转义
    一、定义addslashes()函数返回在预定义字符之前添加反斜杠的字符串。预定义字符是:单引号(’)双引号(”)反斜杠(\)NULL注释:默认地,PHP对所有的GET、POST和COOKIE数据自动运行addslashes()。所以您不应对已转义过的字符串使用addslashes(),因为这样会导致双层转义。遇到这种情况时可......
  • 14-DSL查询语法-复合查询-算分函数查询
     复合(compound)查询:复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑。常见的有两种:(1)fuctionscore:算分函数查询,可以控制文档相关性算分,控制文档排名(2)boolquery:布尔查询,利用逻辑关系组合多个其它的查询,实现复杂搜索 相关性算分当我们利用match查询时,文档结果会根据......
  • Perl:sprintf函数
    在Perl中,sprintf是一个用于格式化字符串的函数。它接受一个格式字符串和一系列参数,并返回根据格式字符串格式化后的字符串。sprintf的语法如下:sprintfFORMAT,LIST其中,FORMAT是格式字符串,指定了输出的格式。LIST是需要格式化的参数列表。sprintf将根据格式字符串对参数......
  • Python 2-04 匿名函数
    Python匿名函数一、匿名函数lambdaλlambda[args]:expression即lambda[参数列表]:表达式lambda_add=lambdax,y:x+ydefnormal_add(x,y):returnx+yassertlambda_add(2,3)==normal_add(2,3)注:assertexpression[,arguments]即:assert表达式......
  • Python 2-03 递推和递归
    递推和递归一、递推算法Recursionmethod递推算法是通过已知条件,利用特定关系得出中间推论,直至得到结果的算法。递推算法分为顺推和逆推两种。动态规划1、顺推法所谓顺推法是从已知条件出发,逐步推算出要解决的问题的方法叫顺推。#n!阶乘deffactorial(n):t=1fori......