方法递归详解

news2024/9/23 3:17:51

什么是方法递归

方法直接调用自己或者间接调用自己的形式称为方法递归( recursion)。 递归做为一种算法在程序设计语言中广泛应用。

递归的形式

直接递归:方法自己调用自己。

间接递归:方法调用其他方法,其他方法又回调方法自己。

方法递归存在的问题?

递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出现象。

案例

/**
         递归的形式
 */
public class RecursionDemo01 {
    public static void main(String[] args) {
        test2();
    }

    public static void test(){
        System.out.println("=======test被执行========");
        test(); // 方法递归 直接递归形式
    }

    public static void test2(){
        System.out.println("=======test2被执行========");
        test3(); // 方法递归 间接递归
    }

    private static void test3() {
        System.out.println("=======test3被执行========");
        test2();
    }
}

执行结果: 

 

递归案例导学-计算1-n的阶乘

需求:

计算1-n的阶乘的结果,使用递归思想解决,我们先从数学思维上理解递归的流程和核心点。

分析:

假如我们认为存在一个公式是 f(n) = 1*2*3*4*5*6*7*…(n-1)*n;

那么公式等价形式就是: f(n) = f(n-1) *n。

如果求的是 1-5的阶乘的结果,应用上述公式手工计算如下:

先往下走

f(5) =  f(4) * 5

f(4) =  f(3) * 4

f(3) =  f(2) * 3

f(2) =  f(1) * 2

f(1) =  1

然后再往回走,就能计算出结果。

代码:

/**
      目标:递归的算法和执行流程
 */
public class RecursionDemo02 {
    public static void main(String[] args) {
        int result = f(5);
        System.out.println("5的阶乘是:"+result);
    }

    public static int f(int n){
        if(n == 1){
            return 1;
        }else {
            return f(n - 1) * n;
        }
    }
}

执行流程

随着程序的执行,方法依次入栈,如下:

 

然后从上往下方法依次被执行完,那么依次被弹栈。

递归解决问题的思路

把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。

递归算法三要素

递归的公式: f(n) =  f(n-1) * n;

递归的终结点:f(1)

递归中的递推方向必须走向终结点。

递归算法

分析问题时能分析出每一步或者每一大步都是在做同样的事情,方可用递归算法。假设方法f(n)能解决复杂问题,再把方法f(n)化为更小规模问题解决方法f(n+1),再把f(n+1)化为更更小的问题解决方法,直到最小问题的解决。

递归的经典问题

猴子第一天摘下若干桃子,当即吃了一半,觉得好不过瘾,于是又多吃了一个。 第二天又吃了前天剩余桃子数量的一半,觉得好不过瘾,于是又多吃了一个。 以后每天都是吃前天剩余桃子数量的一半,觉得好不过瘾,又多吃了一个。 等到第10天的时候发现桃子只有1个了。

需求:请问猴子第一天摘了多少个桃子?

分析: 整体来看,每一天都是做同一个事件,典型的规律化问题,考虑递归三要素:

        递归公式:

              f(x) - f(x)/2 - 1 = f(x+1)
              2f(x) - f(x) - 2 = 2f(x + 1)
              f(x) = 2f(x + 1) + 2

        递归终结点:f(10) = 1。

        递归方向:为了求f(1)逐渐递推到f(10),所以是走向终结点。

代码:

public class RecursionDemo04 {
    public static void main(String[] args) {
        System.out.println(f(1));
        System.out.println(f(2));
        System.out.println(f(3));
    }

    public static int f(int n){
        if(n == 10){
            return 1;
        }else {
            return 2 * f(n + 1) + 2;
        }
    }
}

非规律化递归问题解决方法

非规律化递归问题自己看着办,需要流程化的编程思维,即模拟用户解决问题的过程。

非规律化递归案例-文件搜索

需求:从D:盘中,搜索出某个文件名称并输出绝对路径。

分析:

        先得到目标文件夹(D:\)下的一级文件对象

        遍历全部一级文件对象,判断是否是文件

        如果是文件,判断是否是自己想要的

        如果是文件夹,重复上述过程

代码:

/**
    目标:去D判断搜索 eDiary.exe文件
 */
public class RecursionDemo05 {
    public static void main(String[] args) {
        // 2、传入目录 和  文件名称
        searchFile(new File("D:/") , "eDiary.exe");
    }

    /**
     * 1、搜索某个目录下的全部文件,找到我们想要的文件。
     * @param dir  被搜索的源目录
     * @param fileName 被搜索的文件名称
     */
    public static void searchFile(File dir,String fileName){
        // 3、判断dir是否是目录
        if(dir != null && dir.isDirectory()){
            // 可以找了
            // 4、提取当前目录下的一级文件对象
            File[] files = dir.listFiles(); // null  []
            // 5、判断是否存在一级文件对象,存在才可以遍历
            if(files != null && files.length > 0) {
                for (File file : files) {
                    // 6、判断当前遍历的一级文件对象是文件 还是 目录
                    if(file.isFile()){
                        // 7、是不是咱们要找的,是把其路径输出即可
                        if(file.getName().contains(fileName)){
                            System.out.println("找到了:" + file.getAbsolutePath());
                            // 启动它。
                            try {
                                Runtime r = Runtime.getRuntime();
                                r.exec(file.getAbsolutePath());
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }else {
                        // 8、是文件夹,需要继续递归寻找
                        searchFile(file, fileName);
                    }
                }
            }
        }else {
            System.out.println("对不起,当前搜索的位置不是文件夹!");
        }
    }
}

非规律化递归案例-啤酒问题

需求:啤酒2元1瓶,4个盖子可以换一瓶,2个空瓶可以换一瓶, 请问10元钱可以喝多少瓶酒,剩余多少空瓶和盖子。

答案:15瓶 3盖子 1瓶子。

/**
    目标:啤酒2元1瓶,4个盖子可以换一瓶,2个空瓶可以换一瓶,
        请问10元钱可以喝多少瓶酒,剩余多少空瓶和盖子。
        答案:15瓶 3盖子 1瓶子

 */
public class RecursionDemo06 {

    // 定义一个静态的成员变量用于存储可以买的酒数量
    public static int totalNumber; // 总数量
    public static int lastBottleNumber; // 记录每次剩余的瓶子个数
    public static int lastCoverNumber; // 记录每次剩余的盖子个数


    public static void main(String[] args) {
        // 1、拿钱买酒
        buy(10);
        System.out.println("总数:" + totalNumber);
        System.out.println("剩余盖子数:" + lastCoverNumber);
        System.out.println("剩余瓶子数:" + lastBottleNumber);
    }

    public static void buy(int money){
        // 2、看可以立马买多少瓶
        int buyNumber = money / 2; // 5
        totalNumber += buyNumber;

        // 3、把盖子 和瓶子换算成钱
        // 统计本轮总的盖子数  和 瓶子数
        int coverNumber = lastCoverNumber + buyNumber;
        int bottleNumber = lastBottleNumber + buyNumber;

        // 统计可以换算的钱
        int allMoney = 0;
        if(coverNumber >= 4){
            allMoney += (coverNumber / 4) * 2;
        }
        lastCoverNumber = coverNumber % 4;

        if(bottleNumber >= 2){
            allMoney += (bottleNumber / 2) * 2;
        }
        lastBottleNumber = bottleNumber % 2;

        if(allMoney >= 2){
            buy(allMoney);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1131914.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Postman中几个body请求格式区别及使用说明

参阅:https://blog.csdn.net/qq_41063141/article/details/101505956,在此基础上添加代码使用说明 一、Params与Body 二者区别在于请求参数在http协议中位置不一样。 Params 它会将参数放入url中以?区分以&拼接 Body则是将请求参数放在请…

39.B树,B+树(王道第7章查找补充知识)

目录 一. B树 (1)B树的定义 (2)B树的高度 (3)B树的插入 (4)B树的删除 二. B树 (1)B树的定义 (2)B树与B树的区别 一. B树 &am…

什么是自动证书管理环境(ACME)

组织的网站需要 24x7 全天候可用,以建立信任并提供信息,如果网站因证书过期而停机,那么很难恢复失去的客户信任、收入和品牌声誉,手动管理证书基础结构会使组织面临中断、中间人 (MITM) 攻击等的严重风险。…

新上线游戏产品需不需要防御?

游戏运营免不了遭受恶意DDoS和CC攻击,且攻击常达百G以上,攻击流量过大,超过一般服务器的基础防护能力,不少企业面对大流量攻击显得束手无策,只能选择被迫停机,其次游戏行业利润高,很容易被黑客盯…

智慧矿山:如何快速识别带式运输机空载状态!

带式运输机作为一种常见的物料输送设备,广泛应用于矿山、建筑、化工等行业。但在使用过程中,经常会出现空载运行的情况,即带式运输机无物料传送时仍不停工作,导致能源和设备的浪费。因此,对带式运输机进行空载识别并采…

【期刊】IEEE系列指定期刊模版下载(LaTeX或者Word)全网最细教程

IEEE旗下有很多期刊,例如: IEEE Transactions on Pattern Analysis and Machine Intelligence IEEE Transactions on Cybernetics IEEE Transactions on Neural Networks and Learning Systems IEEE Transactions on Industrial Informatics IEEE Tra…

代理服务器可能有问题,或地址不正确的解决办法

问题: 解决办法: 1.找到代理服务器设置 2.代理服务器,设置关闭

基于springboot实现在线考试平台管理系统【项目源码+论文说明】计算机毕业设计

基于Springboot实现在线考试平台管理系统演示 摘要 网络的广泛应用给生活带来了十分的便利。所以把在线考试管理与现在网络相结合,利用java技术建设在线考试系统,实现在线考试的信息化管理。则对于进一步提高在线考试管理发展,丰富在线考试管…

[笔记] Windows 审计《一》判断是否SACL系统记录权限、DACL管理权限是否继承

文章目录 前言代码总结 前言 安全对象:由微软定义为可以具有安全描述符的对象,包括诸如文件,线程,远程注册表,Active Directory对象等许多东西。 安全描述符:包含许多字段的二进制结构,包括对…

K-Means和KNN

主要区别 从无序 —> 有序 从K-Means —> KNN KNN:监督学习,类别是已知的,对已知分类的数据进行训练和学习,找到不同类的特征,再对未分类的数据进行分类。K-Means:无监督学习,事先不知道…

一套成熟的ERP系统,应具备哪些能力?

随着制造业数字化、智能化的不断升级,企业的金字塔静态管理模式也在向扁平化动态管理模式转变,而企业管理系统则是推动这一趋势发展的重要载体。 为了更好地实现企业管理信息化,越来越多的企业在应用ERP系统。ERP对企业经营起着至关重要的辅…

Kafka-Java一:Spring实现kafka消息的简单发送

目录 写在前面 一、创建maven项目 二、引入依赖 2.1、maven项目创建完成后,需要引入以下依赖 2.2、创建工程目录 三、创建生产者 3.1、创建生产者,同步发送消息 3.2、创建生产者,异步发送消息 四、同步发送消息和异步发送消息的区别…

ChinaSoft 论坛巡礼 | 开源软件生态健康度量论坛

2023年CCF中国软件大会(CCF ChinaSoft 2023)由CCF主办,CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办,将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

京东销量(销额)数据分析:2023年9月京东奶粉行业品牌销售排行榜

鲸参谋监测的京东平台9月份奶粉市场销售数据已出炉! 根据鲸参谋平台的数据显示,今年9月份,京东平台奶粉(包括婴幼儿奶粉、孕妈奶粉、婴幼儿液态奶)市场的销量约730万,环比降低约6%,同比降低约19…

【C语言】指针那些事(上)

C语言系列 文章目录 文章目录 一. 字符指针 一.(1 ) 数组创建空间的地址和指针指向的地址 二. 指针数组 二.(1)指针数组模拟一个二维数组 ​ 三. 数组指针 三.(1)数组指针到底有什么用 对一维数组没有什么用 二.(…

VC++程序崩溃时,使用Visual Studio静态分析dump文件

1、通过Visual Studio直接把Dump文件打开 2、点击【仅限本机进行调试】,启动Dump 3.1、本机调试启动后,如果程序运行模块和pdb文件在同一个目录的,直接定位到异常代码行 3.2、如果显示找不到pdb文件,则需要通过【新建路径】设置…

Python-列表、元组和字典

目录 一、列表概述 二、列表的循环遍历 1、使用for循环遍历列表 2、使用while循环遍历列表 三、列表的常见操作 1、在列表中增加元素 (1)使用append方法 (2)使用extend方法 (3)使用insert方法 2、…

温馨提示!小心不法分子的隐藏陷阱

《绝地求生》国服的”老兵回归”活动一经推出就受到广大玩家欢迎,因此也有不法分子想趁虚而入。就在近日,我们接到玩家举报,发现一些不法分子通过伪基站邮件群发的形式,以“第XXXX位老兵奖励”为主题,向用户推荐一个非…

【薅羊毛】免费领取6个月语雀会员-关于语雀 23 日故障的公告

关于语雀 23 日故障的公告 关于语雀 23 日故障的公告 语雀团队 语雀 2023-10-24 21:11 发表于浙江 各位语雀的用户: 10 月 23 日语雀出现重大服务故障,且持续 7 个多小时才完全恢复,给用户使用造成极大不便,对此我们深感抱歉。…

Go 包操作之如何拉取私有的Go Module

Go 包操作之如何拉取私有的Go Module 在前面,我们已经了解了GO 项目依赖包管理与Go Module常规操作,Go Module 构建模式已经成为了 Go 语言的依赖管理与构建的标准。 在平时使用Go Module 时候,可能会遇到以下问题: 在某 modul…