【Python函数的递归】

2023-11-18

递归的定义

函数作为一种代码封装,可以被其他程序调用,当然,也可以被函数内部代码调用。这种函数定义中调用函数自身的方式称为递归。就像一个人站在装满镜子的房间中,看到的影像就是递归的结果。递归在数学和计算机应用上非常强大,能够非常简洁的解决重要问题。

以求阶乘为例

#计算阶乘:根据用户输入的整数n,计算并输出n的阶乘值。
def fact(n):#计算阶乘
    if n == 0:
        return 1
    else:
        return n * fact(n-1)

num = eval(input("请输入一个正整数: "))
print(fact(num))

递归函数调用过程 

递归的思想

把规模大的问题转化为规模小的、具有与原来问题相同解法的问题来解决。在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况。

递归的使用方法

  1. 找到递归关系,即把一个复杂的问题转化为与它形式相似、但规模较小的问题
  2. 找到递归出口,即问题转化时,当规模足够小,可以直接求解

递归法练习

1.字符串反转      

对于用户输入的字符串s,输出反转后的字符串。解决这个问题的基本思想是把字符串看作一个递归对象。    

def rev(s):  # 反转字符串
    if len(s) == 1:
        return s
    else:
        return s[-1]+rev(s[:len(s)-1])


s = input()
print(rev(s))


2.斐波那契数列(1、1、2、3、5、8、13、21、34、……)

兔子繁殖问题:

在700多年前,意大利著名数学家斐波那契在《算盘全集》中提到这样一个问题:一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假如兔子都不死,请问第1个月出生的一对兔子,第n个月有多少对兔子?

F(1)=1

F(2)=1

F(3)=F(1)+F(2)=1+1=2

F(4)=F(2)+F(3)

…………

F(N)=F(N-2)+F(N-1)

代码

def fab(n):
    if n <= 2:
        return 1
    else:
        return fab(n-1)+fab(n-2)


n = eval(input())
print(fab(n))

 斐波那契的递归实现版本里面有很多冗余计算,可以通过增加缓存来优化。

# -*- coding: UTF-8 -*-
# 斐波那契数列 递归
def fibonacci_inner(n, cache):
    if n == 1 or n == 2:
        return 1
    r = 0
    # 实现缓存
    if cache.get(n) is not None:
        return cache[n]
    else:
        cache[n] = fibonacci_inner(n-1, cache) + fibonacci_inner(n-2, cache)
    return cache[n]


def fibonacci(n):
    return fibonacci_inner(n, {})


if __name__ == '__main__':
    n = eval(input())
    print(fibonacci(n))

3.赶鸭子问题

题目描述

一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?

分析

设经过的村子为n (n = 0,1,2,...,7),根据题目分析可知递归结束的出口: n = 7时,剩余鸭子数duck = 2;

分析递归体:从后向前推 n=7时 ,duck = 2, 由于每经过一个村子,卖去所赶鸭子的一半又一只,因此七个村子后剩余的鸭子数 duck[7]=duck[6]-(duck[6]/2+1)

反推duck[6] = (duck[7] + 1) * 2

最终递归体: (duck[n+1] + 1) * 2;

综上  

n=7    duck=2
0<=n<7   duck=(duck(n+1) + 1) * 2

代码

def duck(n):
    if n == 7:
        return 2
    else:
        return (duck(n+1)+1)*2


print("鸭子的总数为:{}".format(duck(0)))
sum = duck(0)
for i in range(1, 8):
    print("第{}个村庄卖出{}只鸭子,剩余鸭子数为{}". format(i, sum-duck(i), duck(i)))
    sum = duck(i)

运行结果


4.角谷定理

题目描述

角谷定理。输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1。

示例 输入 输出
示例1 22

11 34 17 52 26 13 40 20 10 5 16 8 4 2 1

step=15

示例2 33

16 8 4 2 1 

step=5

问题分析

递归出口:当输入的数字为1时,则直接输出

递归体:当输入数据不为1时

  • 当数据为偶数:除以2,递归直到数据为1,输出
  • 当数据为奇数:乘3再加1,递归直至数据为1,输出
# 角谷定理
def jiaogu(step, n):
    if n == 1:
        return step
    else:
        if n % 2 == 0:
            step += 1
            print("{:.0f}".format(n/2), end=" ")
            return jiaogu(step, n/2)
        else:
            step += 1
            print("{:.0f}".format(n*3+1), end=" ")
            return jiaogu(step, n*3+1)


n = eval(input())
m = jiaogu(0, n)
print("\n需要经过{}次运算".format(m))

5.分橘子问题

题目描述

日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。分完 后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7给老三;老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。结果大家手中的桔子正好一样多。问六兄弟原来手中各有多少桔子?

分析:

老大得到老六分给的桔子后,每个人的桔子总数为总数的平均即2520/6=420个

针对老大所得桔子数 = (420 - 从老六那里所得桔子数)*8/7, 老六分给老大其1/3之后剩余420个,因此他有420*3/2 = 630个桔子,即分给老大210个

则可以算出老大在得到老六桔子之前有420-210 = 210个由于老大将其1/8分给老二,则可算出老大最初拥有240个桔子

......

代码

'''
n  表示第几个儿子
beforenum  表示分配之前的橘子数
afternum  表示分配之后的橘子数
m  表示分配的比例
'''


def orange(n, beforenum, afternum, m):
    if n > 6:
        return 0
    else:
        print("老" + str(n) + "原有橘子数" + str(beforenum) + "个")
        # 分给下一个人的橘子数
        givenum = afternum / m
        # 下一个人的橘子数
        nextbeforenum = 420 * (m - 1) / (m - 2) - givenum
        # 下一人加上之前的橘子数的总数
        aftergetnum = nextbeforenum + givenum
        return orange(n + 1, nextbeforenum, aftergetnum, m - 1)


orange(1, 240, 240, 8)

运行结果


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Python函数的递归】 的相关文章

随机推荐

  • 如何把极坐标化为直角坐标_如何将极坐标转化为直角坐标

    展开全部 极坐标转换为直角坐标 32313133353236313431303231363533e58685e5aeb931333366306532 转化方法及其步骤 第一步 把极坐标方程中的 整理成cos 和sin 的形式 第二步 把co
  • 基础15:npm、yarn、pnpm

    npm2 用 node 版本管理工具把 node 版本降到 4 那 npm 版本就是 2 x 了 执行 npm init npm install express 可以看到node modules目录如下 可以看到 npm2的node mod
  • 深入理解计算机系统(2.3)---整数的表示方式精解》无符号与补码编码(重要)...

    上一章我们简单的介绍了布尔代数以及C语言的位运算 本次我们主要来看 二进制如何表示整数 这是很重要的一章 希望各位猿友莫要错过 C语言中的整数类型及范围 我们依然以C语言为例 C语言当中提供了多种整数类型 一共十种 位数为1 2 4 8 其
  • ShellExecuteEx中与被调进程同步

    在实际的开发中会遇到这样的情况 A进程在运行时 需要调起B进程完成某些工作 例如取回关键文件 且必须等待该进程完成工作结束后才能往下继续 那么这时候 就可以采用ShellExecuteEx和WaitForSingleObject的结合对被调
  • 新媒体运营怎么追热点?这四个技巧一定可以帮到你

    作为一个新媒体运营 热点追不好 冷板凳少不了 热点追得好不但能带来账号的曝光 还能带来良好的涨粉效果 但是很多人都不知道热点到底要怎么追 那么今天就给大家分享一下 追热点4个百试不爽的套路 01 怎样找热点 热点可以分为常规型热点和突发型热
  • R语言——数据排序

    R语言中涉及排序的基本函数有order sort和rank三个 下面看看它们的基本用法 x表示需要排序的数据 decreasing表示是否按降序排序数据 method表示所使用的排序算法 na last表示如何处理NA值 缺失值 若为FAL
  • eclipse中导入idea项目的基本步骤

    eclipse导入idea项目 前段时间有个idea项目 SSM maven 需要导入eclispe运行 最后搞了很久才运行成功 这里整理一下导入项目时需要修改一些配置 第一步 import时建议选择导入Maven项目 选择Maven下的导
  • 在Centos7中搭建http服务器

    一 简介 二 安装 二 编辑配置文件 三 配置主页文件 或者将做好的网站放入根目录 四 配置安全访问规则 五 启动http服务 六 访问测试 七 心得体会 一 简介 Centos7默认的http服务器为Apache Apache HTTP
  • Python提取网页信息并保存

    使用Python爬取网页内容时 获取网页源码文件后使用一系列解析方法提取我们需要的信息 对于提取到的信息怎么保存下来 本文提供常见的两种方法 保存到本地文件或MySQL数据库 保存到本地csv文件 将数据以一定的格式保存到本地csv文件需要
  • 修改cdh6.3.2集群内部弱口令步骤

    在这里插入图片描述 cdh管理页面修改 hive hue oozie 密码 主节点修改 另外修订mysql数据库内密码 首先登陆mysql 具体参考 https blog csdn net weixin 43214644 article d
  • STM32---外部中断

    目录 1 外部中断描述 2 外部中断框图 总结 经过分析框图 可以产生软件中断和事件中断 软件中断的目的是进中断服务函数 事件中断是产生一个脉冲信号给片内外设 属于硬件级别的 3 各寄存器作用 4 端口对应 5 编程思路 EXIT NVIC
  • mysql8.0出现group by报错

    数据库跟目录执行set GLOBAL sql mode STRICT TRANS TABLES NO ZERO IN DATE NO ZERO DATE ERROR FOR DIVISION BY ZERO NO ENGINE SUBSTI
  • Qt 使用笔记 --转自 wangwenx190/Note

    转自 https github com wangwenx190 notes blob master qt zh cn md Qt 使用笔记 Qt 6 目标平台变更 Qt6 不再支持32位Windows系统 不再支持Windows 7 Win
  • pageHelper.startPage(m,n)的用法

    pageHelper startPage m n 的用法 pageHelper startPage m n 是分页查询 PageHelper startPage m n 两个参数 第一个参数是页数 第二个参数是条数 每页查询的条数 例如我想
  • 疯壳AI开源无人机SPI(六轴传感器数据获取)

    一 ICM20602简介 六轴传感器在当今智能穿戴和定位导航产品中被广泛应用 而六轴传感器中做的最好的要属InvenSense公司的产品了 ICM20602便是其推出的优秀六轴传感器之一 ICM20602集成3轴加速度计和3轴陀螺仪 其中陀
  • bat命令备份oracle数据库,并且删除7天之前的数据文件

    用批处理命令备份oracle数据库 我是用在windows server 2008 服务器上 并且创建了定时任务 让他7天执行一次 下面贴出代码 echo off echo echo Windows环境下Oracle数据库的自动备份脚本 e
  • Fast DDS入门五、在Windows平台创建一个简单的Fast DDS示例程序

    1 创建简单示例程序 在这里 先建立一个IDL文件 然后通过使用Fast DDS Gen生成程序生成这个简单示例程序 Fast DDS Gen程序的编译安装请参考 Fast DDS入门二 Fast DDS在Windows平台的编译安装 Fa
  • 狂热的NFT,泡沫还是风口?

    比特币市场狂热的NFT今年以来 不仅 元宇宙 爆火 NFT Non Fungible Token 非同质化代币 也掀起一波波炒作热潮 3月份 数字艺术家Beeple的NFT作品 每一天 前5000天 在佳士得拍卖行以6934万美元成交 创造
  • 解决查询时报的cannot be cast to com.credithc.enjoy.manager.OrderResp错误

    报的错误如下所示 14 30 54 637 ERROR http nio 8094 exec 4 127 0 0 1 f6c45349d812457bbb5e42bc3a1bc09d 1 0 com credithc enjoy manag
  • 【Python函数的递归】

    递归的定义 函数作为一种代码封装 可以被其他程序调用 当然 也可以被函数内部代码调用 这种函数定义中调用函数自身的方式称为递归 就像一个人站在装满镜子的房间中 看到的影像就是递归的结果 递归在数学和计算机应用上非常强大 能够非常简洁的解决重