java递归练习

File类递归练习

从键盘接收一个文件夹路径,统计该文件夹大小

题解: 

  1. 创建键盘录入对象
  2. 定义无限循环
  3. 将键盘录入对象的结果存储并封装成File对象
  4. 对File对象进行判断
  5. 将该文件夹路径对象返回
  6. 定义一个求和变量
  7. 获取该文件下所有文件和文件夹listFiles()
  8. 遍历数组
  9. 判断是文件就计算并累计大小
  10. 判断是文件夹递归调用
import java.io.File;
import java.util.Scanner;
public class test1 {
    public static void main(String[] args) {
        File dir = getDir();
        System.out.println(get(dir));
    }
    public static File getDir() {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入文件夹路径:");
        while(true) {
            String s = sc.nextLine();
            File dir = new File(s);
            if(!dir.exists()){
                System.out.println("您录入的文件夹路径不存在,请重新输入一个文件夹:");
            } else if(dir.isFile()){
                System.out.println("您录入的是一个文件路径,请录入一个文件夹路径:");
            }else {
                System.out.println("录入成功!!!");
                return dir;
            }
        }
    }
    public static Long get(File dir) {
        long len = 0;
        File[] subFiles = dir.listFiles();
        for(File subfile : subFiles){
            if(subfile.isFile()){
                len = len + subfile.length();
            }else{
                len = len + get(subfile);
            }
        }
        return len;
    }
}

删除该文件夹

1.获取该文件夹下所有文件和文件夹

2.遍历数组

3.判断是文件夹就继续递归

4.是文件就直接删除

5.循环结束后删掉空文件夹

import java.io.File;
import java.util.Scanner;
public class test2 {
    public static void main(String[] args) {
       File dir = getdir();
       deletedir(dir);
    }
    public static File getdir() {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个文件夹路径:");
        while(true) {
            String line = sc.nextLine();
            File dir = new File(line);
            if(!dir.exists()) {
                System.out.println("您输入的文件夹路径不存在,请重新输入:");
            } else if(dir.isFile()){
                System.out.println("您输入的是文件路径,请重新输入:");
            } else {
                System.out.println("录入结束");
                return dir;
            }
        }
    }
    public static void deletedir(File dir) {
        File[] subFiles = dir.listFiles();
        for(File f : subFiles) {
            if(f.isDirectory()){
                deletedir(f);
            }else {
                f.delete();
            }
        }
        dir.delete();
    }
}

拷贝

解题思路

从键盘接收两个文件夹路径,把其中一个文件夹内容拷贝到另一个文件夹中

1.键盘录入路径,在目标文件夹中创建原文件夹

2.获取原文件文件夹中的所有文件和文件夹,存储在File数组中

3.遍历数组

4.如果是文件就用io流读写

5.如果是文件夹就递归调用

import java.io.*;


public class test3 {
    public static void main(String[] args) throws IOException {
        File src  = test1.getDir();
        File dest = test1.getDir();
        if(src.equals(dest)) {
            System.out.println("目标文件夹是源文件夹的子文件夹");
        } else {
            copy(src, dest);
        }
    }
    public static void copy(File src,File dest) throws IOException {
        //在目标文件夹中创建原文件夹
        File newDir = new File(dest,src.getName());
        newDir.mkdir();
        //获取源文件夹中所有的文件以及文件夹
        File[] subFiles = src.listFiles();
        for(File f:subFiles){
            if(f.isFile()){
                BufferedInputStream bis  = new BufferedInputStream(new FileInputStream(f));
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(newDir,f.getName())));
                int b;
                while((b = bis.read())!=-1){
                    bos.write(b);
                }
                bis.close();
                bos.close();
            } else {
                copy(f,newDir);
            }
        }
    }
}

 按层级打印

从键盘结构一个文件夹路径,把文件夹中所有文件以及文件夹的名字按层级打印

1.键盘录入文件路径,获取所有文件和文件夹

2.遍历数组

3.不论是文件还是文件夹都需要直接打印

4.如果是文件夹递归调用

import java.io.File;

public class test4 {
    public static void main(String[] args) {
        File dir = test1.getDir();
        int lev = 0;
        printName(dir,lev);
    }

    private static void printName(File dir,int lev) {
        File[] subFiles = dir.listFiles();
        for(File f:subFiles) {
            for(int i = 0 ;i< lev ;i++) {
                System.out.print("\t");
            }
            System.out.println(f.getName());
            if(f.isDirectory()) {
                printName(f,lev+1);  //++lev或者lev++都会改变原来的值
            }
        }
    }
}

斐波那契数列

不死神兔

假设一对刚出生的小兔一个月之后就能长成大兔,再过一个月就能生下一对小兔子,一年内没有发生死亡。则一对刚出生的兔子一年内能繁殖多少对兔子:

  1. 一对小兔子     1
  2. 一对大兔子  一对小兔子 1
  3. 两对大兔子 一对小兔子 2
  4. 三对大兔子 两对小兔子 3
  5. 五对大兔子 三对小兔子 5
  6. 八对大兔子 五对小兔子 8

 可以得到规律本月大兔子对数等于上月大小兔子对数之和,本月小兔子对数等于上月大兔子对数。

代码实现

public class test5 {
    public static void main(String[] args) {
        System.out.println(fun(8));
    }
    public static int fun(int num) { //递归做法
        if(num == 1 || num==2){
            return 1;
        } else {
            return fun(num-1)+fun(num-2);
        }
    }
    public static void arrtest() {  //数组做法
        int[] arr = new int[8];
        arr[0] = 1;
        arr[1] = 1;
        for(int i = 2;i<arr.length;i++){
            arr[i] = arr[i-2] +arr[i-1];
        }
    }
}

1000的阶乘所有零和尾部零的个数

非递归:

import java.math.BigInteger;

public class test6 {
    public static void main(String[] args) {
      BigInteger bi1 = new BigInteger("1");
      for(int i = 1; i<=1000;i++) {   //获取1000阶乘的结果
          BigInteger bi2 = new BigInteger(i + "");
          bi1 = bi1.multiply(bi2);
      }
      String str = bi1.toString();
      int c = 0;
      for(int i = 0;i<str.length();i++){  //求所有零的个数
          if('0' == str.charAt(i)) {
              c++;
          }
      }
      System.out.println(c);
      StringBuilder sb = new StringBuilder(str);  //获取尾部有多少个零
      str = sb.reverse().toString();
      int c2 = 0;
      for(int i = 0;i<str.length();i++){
          if('0' != str.charAt(i)){
              break;
          } else {
              c2++;
          }
      }
      System.out.println(c2);
    }

}

递归写法

5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100...1000    1000 / 5 = 200    5的倍数        产生至少1个0  这些数和任意的偶数相乘,结尾都会是0
5*5 5*5*2 5*5*3 5*5*4 5*5*5 5*5*6 5*5*7 5*5*8 5*5*9 5*5*10...5*5*40       200 / 5 = 40      25的倍数      产生至少2个0  第一次将会产生一个0的都统计了,但还有些数会产生两个0,去掉1个0还剩1个0.
5*5*5 5*5*5*2 5*5*5*3 5*5*5*4 5*5*5*5 5*5*5*6 5*5*5*7 5*5*5*8                 40 / 5 = 8        125的倍数    产生至少3个0  去掉2个0还剩1个0.
5*5*5*5                                                                                                            8 / 5 = 1        625的倍数    4个0  去掉3个0还剩1个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);
		}
	}

约瑟夫环

所有人围成一个圈,数到三和三个倍数就淘汰,最后胜利的人就是赢家

import java.util.ArrayList;

public class test7 {
    public static void main(String[] args) {
        System.out.println(getLuckyNum(8));
    }
    public static int getLuckyNum(int num) {
        ArrayList<Integer> list = new ArrayList<>(); //存储1到num的对象
        for(int i = 1;i<=num;i++){
            list.add(i);
        }
        int count = 1;
        for(int i = 0; list.size() != 1;i++) {
            if(i == list.size()) {  //这样就可以围成一个圈
                i = 0;
            }

            if(count % 3 == 0){ //如果是3的倍数就淘汰
                list.remove(i);
                i--;      //不然就会到下一个,中间会漏掉一个
            }
            count++;
        }
        return list.get(0);
    }
}

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值