欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

day19Java-常用对象IO-递归

程序员文章站 2022-05-09 13:16:37
...

常用对象IO-递归

递归:方法定义中调用方法本身的现象
需求使用递归的关键点:

	A:递归的出口
	B:找出规律

Math.max(Math.max(a,b),c);方法的嵌套调用,这不是递归。

递归代码:

public void show(int n) {
  		if(n <= 0) {
  			System.exit(0);
  		}
  		System.out.println(n);
  		show(--n);
}

递归注意事项:

		A:递归一定要有出口,否则就是死递归
  		B:递归的次数不能太多,否则就内存溢出
  		C:构造方法不能递归使用

举例:

		从前有座山,山里有座庙,庙里有个老和尚和小和尚,老和尚在给小和尚讲故事,故事是:
		从前有座山,山里有座庙,庙里有个老和尚和小和尚,老和尚在给小和尚讲故事,故事是:
		从前有座山,山里有座庙,庙里有个老和尚和小和尚,老和尚在给小和尚讲故事,故事是:
		从前有座山,山里有座庙,庙里有个老和尚和小和尚,老和尚在给小和尚讲故事,故事是:
  		...

递归解决问题思想:

	分解法
	合并法

递归-请用代码实现求5的阶乘

需求:请用代码实现求5的阶乘。
递归解决问题思想图解
day19Java-常用对象IO-递归
分析:

      5!=5*4*3*2*1
      5!=5*4!
有几种方式实现呢?
      A:循环实现
      B:递归实现
          a.做一个递归方法
          b.出口条件
          c.规律

代码演示

public class DiGuiDemo {
    public static void main(String[] args) {
        int jc = 1;
        for (int x = 1; x <=5 ; x++) {
            jc*=x;
        }
        System.out.println(jc);
		System.out.println("-----------");
        int number = diGui(5);
        System.out.println(number);

    }
    public static int diGui(int n){
        //递归出口
        if(n==1){
            return 1;
        }else{
            //规律
            return n*diGui(n-1);
        }
    }
}

结果:

120
-----------
120

递归实现阶乘内存图解
day19Java-常用对象IO-递归

递归-递归实现不死兔

有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第二十个月的兔子对数为多少?

分析:想办法找规律
第一个月: 1
第二个月: 1
第三个月: 2
第四个月: 3
第五个月: 5
第六个月: 8

由此可见兔子对象的数据是:
1,1,2,3,5,8…

规则:

	A:从第三项开始,每一项是前两项之和
  	B:而且说明前两项是已知的

如何实现这个程序呢?

	A:数组实现
  	B:变量的变化实现
  	C:递归实现

如何实现这个程序呢?

	A:数组实现
	B:变量的变化实现
	C:递归实现

假如相邻的两个月的兔子对数是a,b
第一个相邻的数据:a=1,b=1
第二个相邻的数据:a=1,b=2
第三个相邻的数据:a=2,b=3
第四个相邻的数据:a=3,b=5
看到了:下一次的a是以前的b,下一次是以前的a+b

代码演示

public class DiGuiDemo {
    public static void main(String[] args) {
        //方式1:数组实现
        int[] arr = new int[20];
        arr[0] = 1;
        arr[1] = 1;

        for (int x = 2; x < 20; x++) {
            //第三个数是等于第一个数加上第二个数
            arr[x] = arr[x - 2] + arr[x - 1];
        }
        //输出以前的最大索引出的值
        System.out.println(arr[19]);//6765
        System.out.println("------------------");

        //方式2:变量的变化实现
        int a = 1;
        int b = 1;
        for (int x = 0; x < 18; x++) {
            //首先将以前a赋值给一个临时变量
            int temp = a;
            //下一次的a等于以前的b
            a = b;
            //下一次的b等于以前的a+b
            b = temp + b;
        }
        //输出b的值
        System.out.println(b);//6765
        System.out.println("------------------");

        //方式3:递归实现
        int number = fib(20);
        System.out.println(number);
    }

    /*
        递归实现需求关键点:
                    出口:1或者2
                    规律:已经写出来
    */
    public static int fib(int month) {
        if(month==1 || month==2){
            //递归出口
            return 1;
        }else{
            //规律:从第三月份开始,每月份等于前两个月的和
           	//开始我这里有一个疑问,就是如果fib方法参数是3,也就是return fib(2)+fib(1)这样就计算出3月份的兔子个数,
           	//但是此时递归已经到出口了,开始返回数据,但是还没有计算1月份和2月份的兔子个数,其实不用统计1月和2月的兔子个数,
           	//题目要求的是第二十个月的兔子个数,而不是求总数,我只需要一月和二月个数来推断出第二十个月的兔子个数就行了。再说
           	//一月和二月的兔子个数是已知条件。
            return fib(month-1)+fib(month-2);
        }
    }

结果:

6765
------------------
6765
------------------
6765

递归-递归删除带内容的目录

我不只是删除目录中的内容,我是删除指定目录所有内容。(不能指定系统盘)
分析:

  	1.将demo文件夹封装成File对象
  	2.调用递归方法
    3.获取当前文件夹所有内容,判断是否是文件夹
          是:继续调2(其实这里就是递归的出口)
          不是:删除文件

代码演示

public class DiGuiDemo {
    public static void main(String[] args) {
        //封装demo为File对象
        File srcFolder = new File("demo\\a.txt");
        File[] files = srcFolder.listFiles();
        for (File f : files) {
            System.out.println(f);
        }
        System.out.println(Arrays.toString(files));
        //调用方法
        diGui(srcFolder);
    }

    public static void diGui(File srcFolder) {
    	//指定是一个空的目录返回[],指定的是一个文件返回的就是null,又因为增强for的目标不能为null下面加上不为空的判断。
        File[] files = srcFolder.listFiles();
        
        //还有就是,如果删除的是C盘,如果有些是受保护的文,返回的也会是null值
        if (files != null) {
            //删除文件
            for (File file : files) {
                //判断是否是文件
                if (file.isDirectory()) {
                    diGui(file);//递归出口:如果没有目录了就不在递归了
                } else {
                    //删除文件
                    System.out.println(file.getName() + "----" + file.delete());
                }
            }
            //当前目录下文件删除后删除文件夹
            System.out.println(srcFolder.getName() + "----" + srcFolder.delete());
        }
    }
}

结果:

ccc.txt----true
ddd.mp3----true
aaa----true
eee.avi----true
fff.jpg----true
bbb----true
demo----true

递归-把D:\MyWorkSpace目录下所有的java结尾的文件的绝对路径给输出在控制台。

分析:

	    1.封装指定目录对象
        2.编写递归方法
        3.获取D:\MyWorkSpace所有文件和文件夹
        4.判断是否是文件夹
                是:回到2(递归出口)
              	不是:在判断是否以.java结尾
                        是:输出绝对路径
                      	不是:不搭理

代码演示:

public class DiGuiDemo02 {
    public static void main(String[] args) {
        //封装指定目录对象
        File srcFolder = new File("D:\\MyWorkSpace");
        //调用递归
        diGui(srcFolder);
    }

    private static void diGui(File srcFolder) {
        //获取指定目录下文件和文件夹
        File[] files = srcFolder.listFiles();
        //遍历File对象数组
        for (File file : files) {
            //判断是否是目录
            if (file.isDirectory()) {
                diGui(file);//递归出口
            } else {
                //判断是否以.java结尾
                if (file.getName().endsWith(".java")) {
                    System.out.println(file.getAbsolutePath());
                }
            }
        }
    }
}

结果:

D:\MyWorkSpace\basic-code\src\com\ginger\demo01\DiGuiDemo.java
D:\MyWorkSpace\basic-code\src\com\ginger\demo02\DiGuiDemo.java
D:\MyWorkSpace\basic-code\src\com\ginger\demo03\DiGuiDemo.java
D:\MyWorkSpace\basic-code\src\com\ginger\demo03\DiGuiDemo02.java
相关标签: Java相关知识