方法递归调用

news2024/9/22 5:32:14

🏡个人主页 :@ 守夜人st
🚀系列专栏:Java
…持续更新中敬请关注…
🙉博主简介:软件工程专业,在校学生,写博客是为了总结回顾一些所学知识点

✈️推荐一款模拟面试,刷题神器,从基础走向大场面试👉 开启你的刷题之路吧

这里写目录标题

  • 方法递归
    • 递归的形式和特点
      • 什么是方法递归
      • 递归的形式
    • 递归的算法流程、核心要素
      • 案例
      • 递归解决问题的思路
      • 非规律化递归案例
        • 文件搜索
        • 啤酒问题

方法递归

递归的形式和特点

什么是方法递归

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

递归的形式

  • 直接调用:方法自己调用自己
  • 间接调用:方法调用其他方法,其他方法又返回调用自己
package com.shouyeren.algorithm.recursion;

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

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

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

    public static void test2(){
        System.out.println("test方法被执行了");
        test1();
    }
}

递归的方法无限调用自己,无法终止,会出现StackOverflowError 堆栈溢出错误

递归的算法流程、核心要素

案例

需求:计算1—n的阶乘的结果,使用递归思想解决,从数学思维上理解递归的流程和核心点

package com.shouyeren.algorithm.recursion;

/**
 * 递归的算法和执行流程
 */
public class recursionDemo2 {
    public static void main(String[] args) {
        System.out.println(test(5));//120
    }

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

递归解决问题的思路

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

递归算法的三要素大体可以总结为:

  • 递归的公式:f(n) = f(n - 1) * n
  • 递归的终结点:f(1)
  • 递归的方向必须走向终结点

经典案例

猴子吃桃:

猴子第一天摘下若干桃子,当即吃了一半,觉得好吃不过瘾,于是又多吃了一个,之后每天如此,等到第十天的时候发现只有一个桃子了。

请问第一天猴子摘下了多少个桃子?

package com.shouyeren.algorithm.recursion;

/**
 * 猴子吃桃问题
 */
public class recursionDemo4 {
    public static void main(String[] args) {
        System.out.println(test(1));//1534
    }


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

非规律化递归案例

文件搜索

package com.shouyeren.algorithm.recursion;

import java.io.File;

/**
 * 文件搜索递归实现
 */
public class recursionDemo5 {
    public static void main(String[] args) {
        searchFile(new File("D:/"),"更新日志.txt");
    }


    /**
     * 搜索某个目录下的全部文件,找到我们想要的文件
     * @param dir 被搜索的源目录
     * @param fileName 被搜索的文件名
     */
   public static void searchFile(File dir,String fileName){
       if (dir != null && dir.isDirectory()){
           //提取当前文件夹下的一级对象

            File[] files = dir.listFiles();
            //判断该目录是否存在一级文件对象
            if (files != null && files.length > 0){
                //遍历当前文件夹下的一级对象
                for (File file : files) {
                    //判断当前遍历的一级对象是文件还是文件夹
                    if (file.isFile()){
                        //判断文件名是否是搜索的文件
                        if (file.getName().contains(fileName)){
                            System.out.println("找到了文件:" + file.getAbsolutePath());
                        }
                    }else {
                        //一级对象是文件夹,需要递归寻找
                        searchFile(file,fileName);
                    }
                }
            }
       }else {
           System.out.println("对不起,您当前搜索的位置不是文件夹或您要搜索的文件夹不存在!");
       }

   }
}

啤酒问题

需求:

啤酒2元一瓶,四个盖子可以换一瓶,两个空瓶可以换一瓶,请问10元钱可以喝多少瓶啤酒,剩余多少个空瓶和盖子?

package com.shouyeren.algorithm.recursion;

/**
 * 需求:
 * 啤酒2元一瓶,四个盖子可以换一瓶,两个空瓶可以换一瓶,
 * 请问10元钱可以喝多少瓶啤酒,剩余多少个空瓶和盖子?
 */
public class recursionDemo6 {
    //定义一个静态成员变量用于储存可以买的酒的数量
    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("剩余的瓶子数:" + lastBottleNumber);
        System.out.println("剩余的盖子数:" + lastCoverNumber);
    }

    public static void buy(int money){
        //2.统计当前能买多少瓶酒
        int buyNumber = money / 2;
        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/341747.html

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

相关文章

【C++设计模式】学习笔记(4):观察者模式 Observer

目录 简介动机(Motivation)模式定义结构(Structure)要点总结笔记结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金…

渣土车智能识别检测 yolov5

渣土车智能识别检测通过yolov5网络模型深度学习技术,渣土车智能识别检测对禁止渣土车通行现场画面中含有渣土车时进行自动识别监测,并自动抓拍告警。YOLOv5是一种单阶段目标检测算法,该算法在YOLOv4的基础上添加了一些新的改进思路&#xff0…

【Redis场景3】缓存穿透、击穿问题

场景问题及原因 缓存穿透: 原因:客户端请求的数据在缓存和数据库中不存在,这样缓存永远不会生效,请求全部打入数据库,造成数据库连接异常。 解决思路: 缓存空对象 对于不存在的数据也在Redis建立缓存&a…

spark01-内存数据分区数量个数原理

原始代码如下:val conf: SparkConf new SparkConf().setMaster("local[*]").setAppName("wordcount")val scnew SparkContext(conf)val rdd: RDD[Int] sc.makeRDD(List(1,2,3,4)//将处理的数据保存分区文件rdd.saveAsTextFile("output2&…

分布式数据库(ShardingSphere)

单库单表数据量过大导致的问题与应对传统的将数据集中存储至单一数据节点的解决方案,在容量、性能、可用性和运维成本这三方面已经难于满足互联网的海量数据场景。我们在单库单表数据量超过一定容量水位的情况下,索引树层级增加,磁盘 IO 也很…

数据库(六): MySQL的主从复制和读写分离

文章目录一、为什么要使用主从复制和读写分离二、主从复制的原理三、如何实现主从复制3.1 master配置3.2 slave配置3.3 测试主从复制四、读写分离五、缺点一、为什么要使用主从复制和读写分离 注意到主从复制和读写分离一般是一起使用的。目的很简单,就是提高数据库…

Python:路径之谜(DFS剪枝)

题目描述 小张冒充 X 星球的骑士,进入了一个奇怪的城堡。 城堡里边什么都没有,只有方形石头铺成的地面。 假设城堡地面是 nn 个方格。如下图所示。 按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着走&#xf…

Java类和对象超详细整理,适合新手入门

目录 一、驼峰命名法 二、Java注释 三、转义符 四、Java程序它的基本结构是什么? 五、Java中的类 六、创建类 七、定义main方法 八、执行代码输出语句 九、Java中的对象 十、创建对象 十一、类与对象的关系 一、驼峰命名法 包名:多单词组成所…

常用类详解(二)StringBuffer

StringBuffer类: 基本介绍: java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删 很多方法与String相同,但StringBuffer是可变长度的。 StringBuffer是一个容器。 我们进行查看StringBuffer,如下…

fpga设计中如何防止信号被优化

本文分别对quartus和vivado防止信号被优化的方法进行介绍。 为什么要防止信号被优化 ​ 在FPGA开发调试阶段,经常遇到这样的情况,需要临时添加信号,观察信号变化,用来定位代码中存在的问题,很多时候这些临时添加的信…

sg3_utils arm64 静态编译

需求背景 在进行ufs等scsi device测试时,需要进行power mode切换等测试,因此需要有一个简单地工具集来向scsi device(ufs接口)发送scsi命令,比如 scsi reset命令等。在网上调研后发现sg3_utils是一个比较全面的工具。…

本地代码提交至gitee仓库

1、新建仓库 新建一个私人访问的仓库 2、创建公钥 点开cmd 输入ssh-keygen -t rsa -C "xxxxxxxxxx.com" 邮箱填入自己使用的即可。 输入完毕后,连按三次enter。 命令就会执行完毕,会出现这个界面 此时已经代表ssh公钥已经创建完毕。 公…

自动驾驶TPM技术杂谈 ———— 摄像头标定

文章目录介绍摄像头内参标定摄像头模型的建立摄像头坐标系与环境坐标系的转换图像坐标系与图像像素坐标系小孔成像与图像物理坐标系环境坐标系与图像像素坐标系的转换摄像头畸变矫正常见内参标定方法平面标定自标定摄像头间外参标定介绍 标定传感器是自动驾驶感知系统中不可缺少…

Springboot集成工作流Activity

介绍 官网:https://www.activiti.org/ 一 、工作流介绍 1.工作流(workflow) 就是通过计算机对业务流程自动化执行管理,它主要解决的是“使在多个参与这之间按照某种预定义规则自动化进行传递文档、信息或任务的过程&#xff0c…

儿童绘本馆图书借阅租赁知识付费小程序源码交流

1.分类图书 2.书单推荐 4.会员卡次、期限购买 5.借阅时间选择 6.积分签到 7.优惠Q领取 前端uniapp开发 后端thinkphp开发 完全开源 <template> <view class"sp-section sp-index"> <!-- search --> <view class&qu…

【第30天】SQL进阶-查询优化- performance_schema系列实战五:查看最近的事务执行信息(SQL 小虚竹)

回城传送–》《32天SQL筑基》 文章目录零、前言一、 查看最近的事务执行信息数据准备&#xff08;如果已有数据可跳过此操作&#xff09;开启第一个会话&#xff0c;配置启用事务事件开启第二个会话&#xff0c;用于执行事务&#xff0c;并模拟事务回滚第一个会话查询活跃事件第…

详解无线技术标准都使用哪些频段?中国物联网市场又适用哪些频段

由于各行各业都有各自的频段只应用需求&#xff0c;所以一般频段都是由国家来进行分配的。国家设立无线电管理机构&#xff0c;通过拍卖、定价的方法向企业、机构发放频段使用许可。获得许可的机构将会获得拍照。这也就是5G&#xff0c;4G时各运营商获得国家颁发牌照的由来。只…

【QT】TCP通信(QTcpServer 和 QTcpSocket)

目录1. TCP通信概述2. QTcpServer2.1 公共函数2.2 信号2.3 保护函数3. QTcpSocket3.1 公共函数3.2 信号4. 代码示例4.1 服务器端MainWindow.hMainWindow.cpp4.2 客户端MainWindow.hMainWindow.cpp4.3 界面显示1. TCP通信概述 TCP是一种被大多数Internet网络协议&#xff08;如…

【设计模式】我终于读懂了代理模式。。。

&#x1f466;代理模式的基本介绍 1)代理模式&#xff1a;为一个对象提供一个替身&#xff0c;以控制对这个对象的访问。即通过代理对象访问目标对象,这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。 2)被代理的对象可以是远程对象、创建…

SharpImpersonation:一款基于令牌和Shellcode注入的用户模拟工具

关于SharpImpersonation SharpImpersonation是一款功能强大的用户模拟工具&#xff0c;该工具基于令牌机制和Shellcode注入技术实现其功能&#xff0c;可以帮助广大研究人员更好地对组织内部的网络环境和系统安全进行分析和测试。 该工具基于 Tokenvator的代码库实现其功能&a…