• 面试2 --- 递归算法


     1 例:        
     2     //求6的阶乘
     3     public class DiGeiDome {
     4         public static void main(String[] args) {
     5             int sum = getSum(6);
     6             System.out.println(sum);
     7         }
     8         
     9         public static int getSum(int n){//n=3
    10             if (n==1) {
    11                 return 1;
    12             }else{
    13                 return n*getSum(n-1);//3*getSum(2);getSum(2)=2*getSum(1)
    14             }
    15         }
    16     }
    17  

    java中常见的递归使用场景

    1. 子问题须与原始问题为同样的事,且更为简单;
    2. 不能无限制调用本身,须有个出口,化简为非递归状态处理;
    3. 递归的次数不能太多,否则容易造成栈内存溢出(java.lang.StackOverflowError);
    4. 构造方法不能递归调用。

    二、计算任意正整数的阶乘

    由于受到intlong取值范围的限制,将数据转换成BigInteger包装类。但是受到电脑内存的限制,只能计算5000以内的正整数阶乘。

     1 import java.math.BigInteger;
     2 import java.util.Scanner;
     3 
     4 public class Recursion_Demo1 {
     5 
     6     public static void main(String[] args) {
     7         Scanner sc = new Scanner(System.in);
     8         System.out.println("求阶乘:");
     9         System.out.println(getFactorial(sc.nextInt()));
    10     }
    11     
    12     public static BigInteger getFactorial(int num) {
    13         if(num == 1) {
    14             return BigInteger.ONE;
    15         }
    16         return BigInteger.valueOf(num).multiply(getFactorial(num - 1));
    17     }
    18 }

    三、计算文件夹大小

    由于File类下length()(返回值类型为long型)方法只能统计文件的大小,没有方法直接统计文件夹的大小,需要使用递归的方法遍历到所有的文件,并累加,最终计算出文件夹大小。

     1 import java.io.File;
     2 import java.util.Scanner;
     3 public class Recursion_Demo2 {
     4     public static void main(String[] args) {
     5         File dir = getDir();
     6         System.out.println(getFileLength(dir));
     7         System.out.println("统计完成!");
     8     }
     9     
    10     public static File getDir() {
    11         //1,创建键盘录入对象
    12         Scanner sc = new Scanner(System.in);
    13         System.out.println("请输入一个文件夹路径:");
    14         //2,定义一个无限循环
    15         while(true) {
    16             //3,将键盘录入的结果存储并封装成File对象
    17             String line = sc.nextLine();
    18             File dir = new File(line);
    19             //4,对File对象判断
    20             if(!dir.exists()) {
    21                 System.out.println("您录入的文件夹路径不存在,请重新录入:");
    22             }else if(dir.isFile()) {
    23                 System.out.println("您录入的是文件路径,请重新录入:");
    24             }else {
    25                 //5,将文件夹路径对象返回
    26                 return dir;
    27             }
    28         }        
    29     }
    30     public static long getFileLength(File dir) {
    31         //1,定义一个求和变量
    32         long len = 0;
    33         //2,获取该文件夹下所有的文件和文件夹listFiles();
    34         File[] subFiles = dir.listFiles();
    35         //3,遍历数组
    36         if(subFiles != null) {
    37             for (File subFile : subFiles) {
    38                 //4,判断是文件就计算大小并累加
    39                 if(subFile.isFile()) {
    40                     len = len + subFile.length();
    41                     //5,判断是文件夹,递归调用
    42                 }else {
    43                     len = len + getFileLength(subFile);
    44                 }
    45             }
    46         }
    47         return len;
    48     }
    49 }
    View Code

    四、删除指定目录

    File类目录下boolean delete()方法:删除此抽象路径名表示的文件或目录。如果此路径名表示一个目录,则该目录必须为空才能删除。

    因此只能通过遍历目录下所有的文件,并删除。

     1 import java.io.File;
     2 import java.util.Scanner;
     3 public class Recursion_Demo3 {
     4     public static void main(String[] args) {
     5         File dir = getDir();
     6         deleteFile(dir);
     7         System.out.println("删除成功!");
     8     }
     9     public static void deleteFile(File dir) {    
    10         //1,获取该文件夹下的所有的文件和文件夹
    11         File[] subFiles = dir.listFiles();        
    12         //2,遍历数组
    13         if(subFiles != null) {
    14             for (File subFile : subFiles) {
    15                 //3,判断是文件直接删除
    16                 if(subFile.isFile()) {
    17                     subFile.delete();
    18                     //4,如果是文件夹,递归调用
    19                 }else {
    20                     deleteFile(subFile);
    21                 }
    22             }
    23         }
    24         //5,循环结束后,把空文件夹删掉
    25         dir.delete();
    26     }
    27     public static File getDir() {
    28         //1,创建键盘录入对象
    29         Scanner sc = new Scanner(System.in);
    30         System.out.println("请输入一个文件夹路径:");
    31         //2,定义一个无限循环
    32         while(true) {
    33             //3,将键盘录入的结果存储并封装成File对象
    34             String line = sc.nextLine();
    35             File dir = new File(line);
    36             //4,对File对象判断
    37             if(!dir.exists()) {
    38                 System.out.println("您录入的文件夹路径不存在,请重新录入:");
    39             }else if(dir.isFile()) {
    40                 System.out.println("您录入的是文件路径,请重新录入:");
    41             }else {
    42                 //5,将文件夹路径对象返回
    43                 return dir;
    44             }
    45         }
    46     }
    47 }
    View Code

    五、拷贝文件夹

    使用BufferedInputStreamBufferedOutputStream高效的拷贝文件夹。

     1 import java.io.BufferedInputStream;
     2 import java.io.BufferedOutputStream;
     3 import java.io.File;
     4 import java.io.FileInputStream;
     5 import java.io.FileOutputStream;
     6 import java.io.IOException;
     7 import java.util.Scanner;
     8 public class Recursion_Demo4 {
     9     public static void main(String[] args) throws IOException {
    10         System.out.println("请录入源文件夹:");
    11         File src = getDir();
    12         System.out.println("请录入目标文件夹:");
    13         File target = getDir();
    14         if(src.equals(target)) {
    15             System.out.println("无法拷贝");
    16         }else {
    17             copy(src,target);
    18             System.out.println("拷贝成功!");
    19         }
    20     }
    21     public static void copy(File src, File target) throws IOException {
    22         //1,在目标文件夹中创建原文件夹
    23         File newDir = new File(target, src.getName());
    24         newDir.mkdir();
    25         //2,获取原文件夹中所有的文件和文件夹,存储在File数组中
    26         File[] subFiles = src.listFiles();
    27         //3,遍历数组
    28         if(subFiles != null) {
    29             for (File subFile : subFiles) {
    30                 //4,如果是文件就用io流读写
    31                 if(subFile.isFile()) {
    32                     BufferedInputStream bis = new BufferedInputStream(new FileInputStream(subFile));
    33                     BufferedOutputStream bos = new BufferedOutputStream
    34                             (new FileOutputStream(new File(newDir,subFile.getName())));
    35                     
    36                     int b = 0;
    37                     while((b = bis.read()) != -1) {
    38                         bos.write(b);
    39                     }
    40                     
    41                     bis.close();
    42                     bos.close();
    43                     //5,如果是文件夹就递归调用
    44                 }else {
    45                     copy(subFile,newDir);
    46                 }
    47             }
    48         }
    49     }
    50     
    51     public static File getDir() {
    52         //1,创建键盘录入对象
    53         Scanner sc = new Scanner(System.in);
    54         System.out.println("请输入一个文件夹路径:");
    55         //2,定义一个无限循环
    56         while(true) {
    57             //3,将键盘录入的结果存储并封装成File对象
    58             String line = sc.nextLine();
    59             File dir = new File(line);
    60             //4,对File对象判断
    61             if(!dir.exists()) {
    62                 System.out.println("您录入的文件夹路径不存在,请重新录入:");
    63             }else if(dir.isFile()) {
    64                 System.out.println("您录入的是文件路径,请重新录入:");
    65             }else {
    66                 //5,将文件夹路径对象返回
    67                 return dir;
    68             }
    69         }
    70     }
    71 }
    View Code

    六、小结

    1. 其实拷贝文件夹还有更加简单的方法,org.apache.commons.io.FileUtils工具类有一个方法copyDirectoryToDirectory(File source,File target)可以直接完成。具体代码如:FileUtils.copyDirectoryToDirectory(getDir(), getDir());
  • 相关阅读:
    在Ubuntu_meta 16.04中设置默认Python3.5的命令
    树莓派安装中文输入法Fcitx及Google拼音输入法
    树莓派安装ubuntu_meta并配置开发环境
    业务代表模式
    MVC 模式
    访问者模式
    模板模式
    Linux进程调度与抢占
    IP地址
    策略模式
  • 原文地址:https://www.cnblogs.com/spstart/p/11474522.html
Copyright © 2020-2023  润新知