方法的递归

什么是方法递归?

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

递归的形式

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

方法递归存在的问题?

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

递归计算n的阶乘

public class RecursionDemo {
    public static void main(String[] args) {
        System.out.println("5的阶乘 :"+f(5));  //5的阶乘 :120
    }
    private static int f(int n) {
        if(n == 1){
            return 1;
        }else{
            return n*f(n-1);
        }
    }
}

递归解决问题的思路:

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

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

  • 递归的公式
  • 递归的终结点
  • 递归的方向必须走向终结点

递归的常见案例

1、计算1-n的和

public class RecursionDemo2 {
    public static void main(String[] args) {
        System.out.println(sum(5));//15
    }
    
    private static int sum(int n) {
        if(n==1){
            return 1;
        }else{
            return n + sum(n-1);
        }
    }
}

2、猴子吃桃问题

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

/*
  推导
  第一天的桃子 f(x)
  第二天的桃子 f(x+1) = f(x) - f(x)/2 -1
             2f(x+1) = 2f(x) - f(x) -2
             2f(x+1) + 2 = f(x)
  得出公式:f(x) = 2f(x+1) + 2 
 */
public class RecursionDemo3 {
    public static void main(String[] args) {
        System.out.println(f(1));//1534
    }

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

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

分析:

①先定位出的应该是一级文件对象

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

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

④如果是文件夹,需要继续递归进去重复上述过程

import java.io.File;

public class RecursionDemo4 {
    public static void main(String[] args) {
        searchFile(new File("D:/"),"ApiPost_Setup_5.1.1_x64.exe");
    }

    /**
     * 搜索某个目录下的全部文件,找到我们想要的
     * @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("当前搜索的位置不是文件夹");
        }
    }
}

4、啤酒问题

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

public class RecursionDemo5 {

    public static int totalNumber; //总数量
    public static int lastBottleNumber; //记录每次剩余的瓶子个数
    public static int lastCoverNumber; //记录每次剩余的盖子个数

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

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

        //把盖子和瓶子换算成钱
        //统计本轮总的盖子数和瓶子数
        int coverNum = lastCoverNumber + buyNum;
        int bottleNum = lastBottleNumber +buyNum;

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

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

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

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奥利奥是甜的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值