zoukankan      html  css  js  c++  java
  • Java基础(二十二) 递归

    递归

          概述

    • 递归:指的是当前方法调用自己的现象。
    • 递归的分类:
          • 递归分为两类:直接递归和间接递归
          • 直接递归:成为方法自身调用自己的情况
          • 间接递归:可以归结为:方法A调用了方法B,方法B调用了方法C,方法C返回来又调用了方法A。

       注意事项:

        • 递归一定要有边界条件(条件限定),保证递归能够停止下来,否则会发生栈内存溢出。
        • 在递归当中虽然有限定条件,但是递归的次数也不能太多,否则也会发生栈内存异常现象。
        • 构造方法禁止递归。

    使用递归实现累计求和

      计算1~n之间的和

      分析:1+2+3+...+n---->n + (n-1) + (n - 2) + ...+1的累加和,递归调用。

      代码示例:

    1 public static void main(String[] args) {  
    2         int sum = sum(10);
    3         System.out.println(sum);
    4     }
     /*
            定义一个方法,使用递归操作
            1 + 2 + 3+ 4 +...+n
            n+(n-1)+(n-2)+(n-3)+…+1
            已知:
                最大值:n
                最小值:1
                使用递归必须明确:
                        1.递归的结束条件
                        2.递归的目的:获取下一个被加的数字(n-1)
        */
        public static  int sum(int n){
            if(n == 1){
                return  1;
            }
            //获取下一个被加的数字
            return n + sum(n-1);
            //return  n == 1 ? 1 : sum(n-1) + n; 使用三目运算符更方便
    
        }

       备注:使用递归当中,main方法调用sum方法,sum方法会一直调用sum方法,导致在内存当中出现了很多个sum方法(频繁地创建方法、调用方法、销毁方法)效率非常低下,最好的方式就是for循环。

    递归求阶乘

      阶乘:所有小于及等于该数的正整数的乘积。

      n的阶乘:n! = n * (n-1) * (n-2) * (n-3) * ... * 3 * 2 * 1

    代码示例:

    1 public  static  int producr(int n){
    2 
    3         if( n == 1){
    4            return 1;  
    5         }
    6         return producr(n-1) * n;
    7 }        

    使用递归打印多级目录

       代码示例:

     1  public static void main(String[] args) {
     2         // 找到Hello文件的路径
     3         File file = new File("C:\Users\admin\Desktop\Hello");
     4         //调用getAllFiles()
     5         getAllFiles(file);
     6     }
     7 
     8     /*
     9         定义一个方法,参数传递File类型的目录
    10         方法中要对目录进行遍历
    11      */
    12     public static void getAllFiles(File file) {
    13         // 表明file此时是一个目录
    14         System.out.println(file);
    15         //首先先获取到它直接子目录和直接子文件
    16         File[] files = file.listFiles();
    17         // 遍历files目录
    18        if (files != null) {
    19             for (File f : files) {
    20                 //判断如果得到的f是一个目录的,需要再次遍历
    21                 if (f.isDirectory()) {
    22                     //表明f是一个目录,则继续遍历这个目录
    23                     //getAllFiles方法就是获取所有的文件,参数传递的刚好是目录,所以直接调用
    24                     //getAllFiles目录
    25                     System.out.println(f);
    26                     getAllFiles(f);
    27                 } else {
    28                     System.out.println(f);
    29                 }
    30             } 
    31         }
    32     }

    综合案例

      文件搜索

      搜索:C:UsersadminDesktopHello目录中的所有的.txt文件

      分析:

        1.目录搜索,无法判断有多少级目录,所以使用递归,遍历所有的目录

        2.遍历目录的时候,获取的是所有的子文件,通过文件的名称来进行诊断,判断是否符合给定的条件.txt

    代码实现:

     1 public static void main(String[] args) {
     2         //构建一个File对象得到C:UsersadminDesktopHello路径
     3         File file = new File("C:\Users\admin\Desktop\Hello");
     4         getAllTxt(file);
     5 
     6     }
     7     /*
     8         定义一个方法,遍历所有的.txt文件
     9         方法中依然需要传递参数目录 
    10      */ 
    11     public static  void getAllTxt(File dir){
    12         File[] files = dir.listFiles();
    13         //遍历files
    14         if(files != null){
    15             for (File f : files) {
    16                 //判断f是否是一个目录
    17                 if(f.isDirectory()){
    18                     getAllTxt(f);
    19                 }else {
    20                     //先获取文件的名称
    21                     //再次判断名称是否以.txt结尾
    22                     //链式编程
    23                     if(f.getName().toLowerCase().endsWith(".txt")){
    24                         System.out.println(f);
    25                     }
    26                 }
    27             }
    28         }
    29     }

    文件过滤器优化

        java.io.FileFilter是一个接口,是File的过滤器,该接口的对象可以传递给File类的ListFiles(FileFilter)作为参数,接口当中只有一个方法:

       boolean accept(File pathname):测试pathname是否应该包含在当前的File目录中,如果符合返回true

    文件过滤器规则

    文件过滤器规则

    示例代码:

     1  public static void main(String[] args) {
     2         //构建一个File对象得到C:UsersadminDesktopHello路径
     3         File file = new File("C:\Users\admin\Desktop\Hello");
     4         getAllTxt(file);
     5     }
     6     /*
     7         定义一个方法,遍历所有的.txt文件
     8         方法中依然需要传参数目录
     9      */
    10     public static void getAllTxt(File dir) {
    11         //System.out.println(dir);
    12         //File[] files = dir.listFiles();
    13         File[] files = dir.listFiles(new FileFilterImpl());
    14         //遍历files
    15         for (File f : files) {
    16             // 判断f是否是一个目录
    17             if (f.isDirectory()) {
    18                 getAllTxt(f);
    19             } else {
    20                 // 先获取文件的名称
    21                 System.out.println(f);
    22             }
    23         }
    24     }
    25 // 实现类中的代码
    26  @Override
    27 public boolean accept(File pathname) {
    28     if (pathname.isDirectory()) {
    29         return true;
    30     }
    31     return pathname.getName()
    32         .toLowerCase()
    33         .endsWith(".txt");
    34 }

    Lambda优化

      示例代码:

    1  //FilenameFilter接口
    2 File[] files = dir.listFiles((d,name)  -> new File(d,name).isDirectory() || name.toLowerCase().endsWith(".txt"));
    3 //FileFilter接口
    4 File[] files = dir.listFiles(pathname ->pathname.getName().toLowerCase().endsWith(".txt") || pathname.isDirectory());
  • 相关阅读:
    软件架构师是如何工作
    安装flume由于HBASE出现的错误
    学习记录(Python集合)
    bzoj4199: [Noi2015]品酒大会
    清橙A1484
    codeforces 232D Fence
    bzoj2337: [HNOI2011]XOR和路径
    bzoj3143: [Hnoi2013]游走
    codeforces 235 B. Let's Play Osu!
    bestcoder单调区间
  • 原文地址:https://www.cnblogs.com/lk625/p/14135268.html
Copyright © 2011-2022 走看看