JavaSE学习day23(递归练习)

一、从键盘接收一个文件夹路径,统计该文件夹大小
  • 从键盘接收一个文件夹路径
  • 1、创建键盘录入对象
  • 2、定义一个无限循环
  • 3、将键盘录入的结果存储并封装成File对象
  • 4、对File对象判断
  • 5、将文件夹路径对象返回
  • 统计该文件夹大小
  • 1、定义一个求和变量
  • 2、获取该文件夹下所有的文件和文件夹listFiles();
  • 3、遍历数组
  • 4、判断是文件就计算大小并累加
  • 5、判断是文件夹,递归调用
import java.io.File;
import java.util.Scanner;

public class Main {
   public static void main (String[] args){
       File dir = getDir();
       System.out.println(getFileLength(dir));
   }

    /*
     * 从键盘接收一个文件夹路径
     * 1,返回值类型File
     * 2,参数列表无
     */
   public static File getDir(){
       //1、创建键盘录入对象
       Scanner sc = new Scanner(System.in);
       System.out.println("请输入一个文件夹路径:");
       //2、定义一个无限循环
       while(true){
           String line = sc.nextLine();
           //3、将键盘录入的结果存储并封装成File对象
           File dir = new File(line);
           //4、对File对象判断
           if(!dir.exists()){
               System.out.println("您录入的文件夹不存在,请重新录入");
           }else if(dir.isFile()){
               System.out.println("您录入的是文件路径,请输入文件夹路径");
           }else{
               //5、将文件夹路径对象返回
               return dir;
           }
       }
   }

    /*
     * 统计该文件夹大小
     * 1,返回值类型Long
     * 2,参数列表File dir
     */
    public static Long getFileLength(File dir){
        // 1、定义一个求和变量
        long len = 0;
        // 2、获取该文件夹下所有的文件和文件夹listFiles();
        File[] subFiles = dir.listFiles();
        //3、遍历数组
        for (File subFile : subFiles) {
            // 4、判断是文件就计算大小并累加
            if(subFile.isFile()){
                len += subFile.length();
            }else if(subFile.isDirectory()){
                len += getFileLength(subFile);
            }
        }
        return len;
    }
二、从键盘接收一个文件夹路径,删除文件夹
  • 从键盘接收一个文件夹路径
  • 1、创建键盘录入对象
  • 2、定义一个无限循环
  • 3、将键盘录入的结果存储并封装成File对象
  • 4、对File对象判断
  • 5、将文件夹路径对象返回
  • 删除该文件夹
  • 1、获取该文件夹下的所有文件和文件夹
  • 2、遍历数组
  • 3、判断是文件直接删除
  • 4、判断是文件夹递归调用
  • 5、循环结束后把空文件夹删掉
import java.io.File;
import java.util.Scanner;

public class Main {
   public static void main (String[] args){
       File dir = getDir();  //获取文件夹路径
       deleteFile(dir);
   }

    /*
     * 从键盘接收一个文件夹路径
     * 1,返回值类型File
     * 2,参数列表无
     */
   public static File getDir(){
       //1、创建键盘录入对象
       Scanner sc = new Scanner(System.in);
       System.out.println("请输入一个文件夹路径:");
       //2、定义一个无限循环
       while(true){
           String line = sc.nextLine();
           //3、将键盘录入的结果存储并封装成File对象
           File dir = new File(line);
           //4、对File对象判断
           if(!dir.exists()){
               System.out.println("您录入的文件夹不存在,请重新录入");
           }else if(dir.isFile()){
               System.out.println("您录入的是文件路径,请输入文件夹路径");
           }else{
               //5、将文件夹路径对象返回
               return dir;
           }
       }
   }

    /*
     * 删除该文件夹
     * 1,返回值类型void
     * 2,参数列表File dir
     */
    public static void deleteFile(File dir){
        // 1、获取该文件夹下所有的文件和文件夹listFiles();
        File[] subFiles = dir.listFiles();
        // 2、遍历数组
        for (File subFile : subFiles) {
            // 3、判断是文件直接删除
            if(subFile.isFile()){
                subFile.delete();
            //4、判断是文件夹递归调用
            }else if(subFile.isDirectory()){
                deleteFile(subFile);
            }
        }
        //5、循环结束后把空文件夹删掉
        dir.delete();
    }
}
三、从键盘接收两个文件夹路径,把其中一个文件夹(包含内容)拷贝到另一个文件夹中
  • 从键盘接收文件夹路径
  • 1、创建键盘录入对象
  • 2、定义一个无限循环
  • 3、将键盘录入的结果存储并封装成File对象
  • 4、对File对象判断
  • 5、将文件夹路径对象返回
  • 把其中一个文件夹(包含内容)拷贝到另一个文件夹中
  • 1、在目标文件夹中创建原文件夹
  • 2、获取原文件夹中所有的文件和文件夹
  • 3、遍历数组
  • 4、如果是文件就io流读写
  • 5、如果是文件夹就递归调用
import java.io.*;
import java.util.Scanner;

public class Main {
   public static void main (String[] args) throws IOException{
       File dir1 = getDir();  //获取文件夹路径
       File dir2 = getDir();
       if(dir1.equals(dir2)){
           System.out.println("目标文件夹是原文件夹的子文件夹");
       }else{
           copy(dir1,dir2);
       }
   }

    /*
     * 从键盘接收一个文件夹路径
     * 1,返回值类型File
     * 2,参数列表无
     */
   public static File getDir(){
       //1、创建键盘录入对象
       Scanner sc = new Scanner(System.in);
       System.out.println("请输入一个文件夹路径:");
       //2、定义一个无限循环
       while(true){
           String line = sc.nextLine();
           //3、将键盘录入的结果存储并封装成File对象
           File dir = new File(line);
           //4、对File对象判断
           if(!dir.exists()){
               System.out.println("您录入的文件夹不存在,请重新录入");
           }else if(dir.isFile()){
               System.out.println("您录入的是文件路径,请输入文件夹路径");
           }else{
               //5、将文件夹路径对象返回
               return dir;
           }
       }
   }

    /*
     * 把其中一个文件夹(包含内容)拷贝到另一个文件夹中
     * 1,返回值类型void
     * 2,参数列表File dir1,File dir2
     */
    public static void copy(File dir1, File dir2) throws IOException {
        //1、在目标文件夹中创建原文件夹
        File newDir = new File(dir2, dir1.getName());
        newDir.mkdir();  //创建文件夹
        //2、获取原文件夹中所有的文件和文件夹
        File[] subFiles = dir1.listFiles();
        //3、遍历数组
        for(File subFile : subFiles){
            //4、如果是文件就io流读写
            if(subFile.isFile()){
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(subFile));
                BufferedOutputStream bos =
                        new BufferedOutputStream(new FileOutputStream(new File(newDir,subFile.getName())));
                int b;
                while((b = bis.read()) != -1){
                    bos.write(b);
                }

                bis.close();
                bos.close();
            //5、如果是文件夹就递归调用
            }else{
                copy(subFile,newDir);
            }
        }
    }
}
四、从键盘接收一个文件夹路径,把文件夹中所有文件以及文件夹的名字按层级打印
  • 从键盘接收文件夹路径
  • 1、创建键盘录入对象
  • 2、定义一个无限循环
  • 3、将键盘录入的结果存储并封装成File对象
  • 4、对File对象判断
  • 5、将文件夹路径对象返回
  • 把文件夹中所有文件以及文件夹的名字按层级打印
  • 1、获取所有的文件和文件夹,返回File数组
  • 2、遍历数组
  • 3、无论是文件还是文件夹都需要直接打印
  • 4、如果是文件递归调用
import java.io.*;
import java.util.Scanner;

public class Main {
   public static void main (String[] args) throws IOException{
       File dir = getDir();  //获取文件夹路径
       printLev(dir,0);
   }

    /*
     * 从键盘接收一个文件夹路径
     * 1,返回值类型File
     * 2,参数列表无
     */
   public static File getDir(){
       //1、创建键盘录入对象
       Scanner sc = new Scanner(System.in);
       System.out.println("请输入一个文件夹路径:");
       //2、定义一个无限循环
       while(true){
           String line = sc.nextLine();
           //3、将键盘录入的结果存储并封装成File对象
           File dir = new File(line);
           //4、对File对象判断
           if(!dir.exists()){
               System.out.println("您录入的文件夹不存在,请重新录入");
           }else if(dir.isFile()){
               System.out.println("您录入的是文件路径,请输入文件夹路径");
           }else{
               //5、将文件夹路径对象返回
               return dir;
           }
       }
   }

    /*
     * 把文件夹中所有文件以及文件夹的名字按层级打印
     * 1,返回值类型void
     * 2,参数列表File dir
     */
    public static void printLev(File dir,int lev) throws IOException {
        // 1、获取所有的文件和文件夹,返回File数组
        File[] subFiles = dir.listFiles();
        // 2、遍历数组
        for(File subFile : subFiles){
            for (int i = 0; i < lev; i++) {
                System.out.print("\t");
            }
            // 3、无论是文件还是文件夹都需要直接打印
            System.out.println(subFile);
            // 4、如果是文件递归调用
            if(subFile.isDirectory()){
                printLev(subFile,lev + 1);
            }
        }
    }
}
五、斐波那契数列:假设一对刚出生的小兔一个月后就能长成大兔,再过一个月就能生下一对小兔,并且此后每个月都生一对小兔,一年内没有发生死亡。问:一对刚出生的兔子,一年内繁殖成多少对兔子?
  • 1 1 2 3 5 8 13
  • 第一个月一对小兔子 1
  • 第二个月一对大兔子 1
  • 第三个月一对大兔子生了一对小兔子 2
  • 第四个月一对大兔子生了一对小兔子,一对小兔子长成大兔子 3
  • 第五个月两对大兔子生了两对小兔子,一对小兔子长成大兔子 5
  • 第三个数等于前两个数的和
	public static void demo1() {
		//用数组做不死神兔
		int[] arr = new int[12];
		//数组中第一个元素和第二个元素都为1
		arr[0] = 1;
		arr[1] = 1;
		//遍历数组对其他元素赋值
		for(int i = 2; i < arr.length; i++) {
			arr[i] = arr[i - 2] + arr[i - 1];
		}
		//如何获取最后一个数
		System.out.println(arr[arr.length - 1]);
	}
//用递归求斐波那契数列
public class Main {
   public static void main (String[] args){
       System.out.println(getNum(12));
   }

   public static int getNum(int month){
       if(month <= 2){
           return 1;
       }else{
           return getNum(month - 1) + getNum(month - 2);
       }
   }
}
六、递归练习:求出1000的阶乘所有0和尾部0的个数,不用递归
  • 因为1000的阶乘远远超出了int的取值范围,所以要用BigInteger
import java.math.BigInteger;

public class Main {
   public static void main (String[] args){
       BigInteger bi1 = new BigInteger("1");
       for (int i = 1; i <= 1000; i++) {
           BigInteger bi2 = new BigInteger(i+"");
           bi1 = bi1.multiply(bi2);
       }
       String str = bi1.toString(); // 获取字符串表现形式
       int count = 0;
       for (int i = 0; i < str.length(); i++) {
           if('0' == str.charAt(i)){ //如果字符串中出现0字符,计数器加1
               count++;
           }
       }
       System.out.println(count);   //所有0

       StringBuilder sb = new StringBuilder(str);
       str = sb.reverse().toString();  //链式编程
       int num = 0;
       for (int i = 0; i < str.length(); i++) {
           if('0' != str.charAt(i)){
               break;
           }else{
               num++;
           }
       }
       System.out.println(num); // 尾部0
   }
}
七、递归练习:求出1000的阶乘所有0和尾部0的个数,用递归
public class Test7 {
	public static void main(String[] args) {
		System.out.println(fun(1000));
	}

	public static int fun(int num) {
		if(num > 0 && num < 5) {
			return 0;
		}else {
			return num / 5 + fun(num / 5);
		}
	}
}
八、集合练习:约瑟夫环,幸运数字
  • N个人围成一圈,从第一个开始报数,第M个或M的倍数个将被杀掉,最后剩下一个,其余人都将被杀掉。
  • 构成一个环:利用指针值,当指针指向size的时候就归0重新开始
import java.util.ArrayList;

public class Main {
   public static void main (String[] args){
       System.out.println(getLucklyNum(8));
   }

   /*
    *获取幸运数字
    * 1.返回值类型int
    * 2.参数列表int num
    */
   public static int getLucklyNum(int num){
       ArrayList<Integer> list = new ArrayList<>(); //创建集合存储1到num的对象
       for (int i = 1; i <= num; i++) {
           list.add(i); //将1到num存储在集合中
       }

       int count = 1;  //用来数数,只要是三的倍数就杀人
       for (int i = 0; list.size() != 1; i++) { //只要集合中人数超过1就要杀
           if(i == list.size()){ //如果i增长到集合最大的索引加1时重新归0
               i = 0;
           }
           if(count % 3 == 0){ //如果是3的倍数就杀人
               list.remove(i--);
           }
           count++;
       }

       return list.get(0);
   }
}

你可能感兴趣的:(学习日志—杂,JavaSE)