File类递归练习
从键盘接收一个文件夹路径,统计该文件夹大小
题解:
- 创建键盘录入对象
- 定义无限循环
- 将键盘录入对象的结果存储并封装成File对象
- 对File对象进行判断
- 将该文件夹路径对象返回
- 定义一个求和变量
- 获取该文件下所有文件和文件夹listFiles()
- 遍历数组
- 判断是文件就计算并累计大小
- 判断是文件夹递归调用
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
- 三对大兔子 两对小兔子 3
- 五对大兔子 三对小兔子 5
- 八对大兔子 五对小兔子 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);
}
}