javaSE (三十四)File类和递归练习(统计文件夹大小、拷贝文件夹、层级打印文件夹、斐波拉契数列、获取1000阶乘全部0和尾部0数目、约瑟夫环)

1、统计文件夹大小:

思路:

  1. 套用之前已经做过的,键入一个路径,若有效则封装成File类
  2. 初始化计数器len,
  3. 若文件夹下是文件,则记录文件.length()
  4. 若文件夹下是文件夹,递归
  5. 输出len

注:递归也可以删除文件夹,但是一定要先删除里面的文件使之为空,才能删除这个文件夹,所以要用到递归删除
代码:

package cn.njupt;

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

public class file {

	private static Scanner sc;

	public static void main(String[] args) throws IOException, ClassNotFoundException {

		sc = new Scanner(System.in);
		System.out.println("请输入一个路径名:");
		File file = getFile(); // 得到一个文件夹名字
		System.out.println(getLength(file));
	}

	public static File getFile() {

		while (true) {
			String line = sc.nextLine(); // 输入一个路径名
			File file = new File(line);// 封装成一个file对象
			if (file.isFile()) {
				System.out.println("这是文件名啊,请重新输入:");
			} else if (!file.exists()) {
				System.out.println("这个文件名不存在,请重新输入:");
			} else {
				return file;
			}
		}
	}

	public static long getLength(File file) {

		File[] subfile = file.listFiles();
		long len = 0;
		for (File file2 : subfile) { // 遍历
			if (file2.isFile()) {
				len = len + file2.length();
			} else if (file2.isDirectory()) {
				len = len + getLength(file2); // 迭代
			}
		}
		return len;
	}

}

2、拷贝文件夹:

注意:目标文件夹一定不能和源文件夹同名,不然会递归死机,可以加个判断语句,利用File重写的equals()方法

package cn.njupt;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

//ObjectOutputStream/ObjectInputStream

public class file {

	private static Scanner sc;

	public static void main(String[] args) throws IOException, ClassNotFoundException {

		// System.out.println(getLength(file));//计算文件大小
		sc = new Scanner(System.in);
		System.out.println("请输入一个源路径名:");
		File src = getFile(); // 得到一个文件夹名字
		System.out.println("请输入一个目的路径名:");
		File dest = getFile(); // 得到一个文件夹名字
		if (src.equals(dest)) {
			System.out.println("目标文件夹是源文件夹的子文件夹,无法拷贝");
		} else {
			copy(src, dest);
		}

		// System.out.println(getLength(file));//计算文件大小
	}

	// C:\Users\pingan\Desktop\111
	public static void copy(File src, File dest) throws IOException {
		File srcInDest = new File(dest, src.getName());// 在目标文件夹下创建源文件夹對象
		srcInDest.mkdir(); // 刚才就差这么一步,获得File对象后还需要创建成文件夹!!!!!
		File[] secSubFile = src.listFiles();
		for (File file : secSubFile) {
			if (file.isFile()) {
				FileInputStream fin = new FileInputStream(file);
				FileOutputStream fout = new FileOutputStream(new File(srcInDest, file.getName()));

				int b;
				while ((b = fin.read()) != -1) {
					fout.write(b);
				}
				fin.close();
				fout.close();
			} else {
				copy(file, srcInDest);
			}
		}

	}

	public static File getFile() {

		while (true) {
			String line = sc.nextLine(); // 输入一个路径名
			File file = new File(line);// 封装成一个file对象
			if (file.isFile()) {
				System.out.println("这是文件名啊,请重新输入:");
			} else if (!file.exists()) {
				System.out.println("这个文件名不存在,请重新输入:");
			} else {
				return file;
			}
		}
	}
}

3、层级打印文件夹:

关键怎么将层级显示出来,在打印文件名之前嵌入一个table

package cn.njupt;

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

public class File2 {

	private static Scanner sc;

	public static void main(String[] args) throws IOException, ClassNotFoundException {

		// System.out.println(getLength(file));//计算文件大小
		sc = new Scanner(System.in);
		System.out.println("请输入一个源路径名:");
		File file = getFile(); // 得到一个文件夹名字
		print(file,0);

	}

	private static void print(File file,int table) {
		
		File[] subFile = file.listFiles();
		
		for (File file2 : subFile) {
			for(int i = 0 ; i <= table ; i++) {
				System.out.print("\t");
			}
			System.out.println(file2.getName()); //第一层,不管是文件还是文件夹,都把名字打印出来
			if (file2.isDirectory()) {  //如果是文件夹,递归
				print(file2,table + 1);	
			}
		}

	}

	

	public static File getFile() {

		while (true) {
			String line = sc.nextLine(); // 输入一个路径名
			File file = new File(line);// 封装成一个file对象
			if (file.isFile()) {
				System.out.println("这是文件名啊,请重新输入:");
			} else if (!file.exists()) {
				System.out.println("这个文件名不存在,请重新输入:");
			} else {
				return file;
			}
		}
	}
}
	

4、斐波拉契数列:

分別用map集合、数组、递归实现斐波拉契数列:

代码:

package cn.njupt;

import java.util.HashMap;

public class Febolaqi {

	public static void main(String[] args) {
		//用map集合实现斐波拉契数列
		fobWithMap(15);
		//用数组实现斐波拉契数列
		fobWithArray(8);
		//用递归实现
		System.out.println(fob(3));	
		
	}

	public static int fob(int len) {
		if(len == 1 || len == 2) {
			return 1;
		}else {
		return fob(len - 1) + fob(len -2);
		}

	}
	
	
	public static void fobWithMap(int len) {
		
		HashMap<Integer, Integer> has = new HashMap<>();
		has.put(1, 1);
		has.put(2, 1);
		for(int i = 3 ; i <= len; i++) {
			has.put(i, has.get(i - 1) + has.get(i - 2));
		}
		System.out.println(has);
	
	}

	
	
	public static void fobWithArray(int lenth){
		int[] arr = new int[lenth];
		arr[0] = 1;
		arr[1] = 1;
		for (int i = 2; i < arr.length; i++) {
			arr[i] = arr[i-1] + arr[i-2];
		}
		
		for (int i : arr) {
			System.out.println(i);
		}
	}
}

5、获取1000阶乘全部0和尾部0数目:

思路:

  1. 1000阶乘数很大,需要用biginteger接受
  2. 用for循环计算尾部0个数(也可以用StringBuilder接受string对象反转从头部奇数,我觉得没必要)
  3. 可以用继续用循环计算全部0个数,但我用了hashmap集合,就和之前计算字符串中字数数量一样,逼格更高

代码:

package cn.njupt;

import java.math.BigInteger;
import java.util.HashMap;

public class Febolaqi {

	public static void main(String[] args) {
		BigInteger big1 = new BigInteger("1");
		for (int i = 1; i <= 1000; i++) {
			BigInteger big2 = new BigInteger(i + "");
			big1 = big1.multiply(big2);
		}
		// System.out.println(big1);

		String str = big1.toString();
		
		char[] arr = str.toCharArray();
		//用map获取所有0
		allZeroWithMap(arr);
		
		//for循环获取尾部0
		tailZeroWithFor(str);

	}

	public static void tailZeroWithFor(String str) {
		int count = 0;

		for (int i = str.length() - 1; i >= 0; i--) {

			if (str.charAt(i) != '0') {
				break;
			} else {
				count++;
			}

		}
		System.out.println(count);
	}

	public static void allZeroWithMap(char[] arr) {
		HashMap<Character, Integer> has = new HashMap<>();
		for (int i = 0; i < arr.length; i++) {
			char a = arr[i];
			has.put(a, (has.containsKey(a) ? has.get(a) + 1 : 1));
		}
		System.out.println(has); // 全部0的个数
	}

}

6、约瑟夫环:

約瑟夫环简介

这里采用“三步杀一人,千里不留行”的步法

代码:

package cn.njupt;

import java.util.ArrayList;

public class Febolaqi {
	// 实现约瑟夫环
	public static void main(String[] args) {
		Josephus(8);
	}

	public static void Josephus(int num) {
		
		//先弄一个监狱,存几个人(这里用arraylist存储,因为remove后会自动往前排)
		ArrayList<Integer> list = new ArrayList<>();
		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) {
				list.remove(i--);//因为remove后会往前排,所以这里往前走一个,后面会加回来
			}

			count++;
			//count和i同时 + 1;
		}
		System.out.println(list.get(0));
	}

}

你可能感兴趣的:(JavaSE,javaSE)