Java基礎複習(四)-遞歸練習

該複習筆記是基於傳智播客的Java基礎視頻-深入簡出精華版,鏈接: https://pan.baidu.com/s/1bp7NuOJ,建議剛剛入門的小白不要看,因爲涉及太多的細節了,看多了反而讓你容易放棄Java之路,剛剛入門的小白推薦下面這一套視頻-鏈接:https://pan.baidu.com/s/1pLuAj5x

博主聲明一下:我不是傳智播客的什麼託,只是一個菜鳥,現在在補着Java基礎,搞了一套傳智播客的Java視頻以及Android視頻,所以筆記可能會常出現這些字眼,請言語諷刺我是託的麻煩你閉嘴哈

File類遞歸調用

File類遞歸調用(統計特定文件夾的大小)

  • 需求:1,從鍵盤接收一個文件夾路徑,統計該文件夾大小
public class Test1 {

    /**
     * @param args
     * 需求:1,從鍵盤接收一個文件夾路徑,統計該文件夾大小
     * 
     * 從鍵盤接收一個文件夾路徑
     * 1,創建鍵盤錄入對象
     * 2,定義一個無限循環
     * 3,將鍵盤錄入的結果存儲並封裝成File對象
     * 4,對File對象判斷
     * 5,將文件夾路徑對象返回
     * 
     * 統計該文件夾大小 
     * 1,定義一個求和變量
     * 2,獲取該文件夾下所有的文件和文件夾listFiles();
     * 3,遍歷數組
     * 4,判斷是文件就計算大小並累加
     * 5,判斷是文件夾,遞歸調用
     */
    public static void main(String[] args) {
        //File dir = new File("F:\\day06");
        //System.out.println(dir.length()); //直接獲取文件夾的結果是0
        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) {
            //3,將鍵盤錄入的結果存儲並封裝成File對象
            String line = sc.nextLine();
            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) {    //dir = F:\day06\day07
        //1,定義一個求和變量
        long len = 0;
        //2,獲取該文件夾下所有的文件和文件夾listFiles();
        File[] subFiles = dir.listFiles();          //day07 Demo1_Student.class Demo1_Student.java
        //3,遍歷數組
        for (File subFile : subFiles) {
            //4,判斷是文件就計算大小並累加
            if(subFile.isFile()) {
                len = len + subFile.length();
            //5,判斷是文件夾,遞歸調用
            }else {
                len = len + getFileLength(subFile);
            }
        }
        return len;
    }
}

這裏寫圖片描述

File類遞歸調用(刪除該文件夾)

  • 需求:2,從鍵盤接收一個文件夾路徑,刪除該文件夾
public class Test2 {

    /**
     * 需求:2,從鍵盤接收一個文件夾路徑,刪除該文件夾
     * 
     * 刪除該文件夾
     * 分析:
     * 1,獲取該文件夾下的所有的文件和文件夾
     * 2,遍歷數組
     * 3,判斷是文件直接刪除
     * 4,如果是文件夾,遞歸調用
     * 5,循環結束後,把空文件夾刪掉
     */
    public static void main(String[] args) {
        File dir = Test1.getDir();                  //獲取文件夾路徑
        deleteFile(dir);
    }

    /*
     * 刪除該文件夾
     * 1,返回值類型 void
     * 2,參數列表File dir
     */
    public static void deleteFile(File dir) {   
        //1,獲取該文件夾下的所有的文件和文件夾
        File[] subFiles = dir.listFiles();      
        //2,遍歷數組
        for (File subFile : subFiles) {
            //3,判斷是文件直接刪除
            if(subFile.isFile()) {
                subFile.delete();
            //4,如果是文件夾,遞歸調用
            }else {
                deleteFile(subFile);            
            }
        }
        //5,循環結束後,把空文件夾刪掉
        dir.delete();
    }

    /*
     * 從鍵盤接收一個文件夾路徑
     * 1,返回值類型File
     * 2,參數列表無
     */
    public static File getDir() {
        //1,創建鍵盤錄入對象
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入一個文件夾路徑:");
        //2,定義一個無限循環
        while(true) {
            //3,將鍵盤錄入的結果存儲並封裝成File對象
            String line = sc.nextLine();
            File dir = new File(line);
            //4,對File對象判斷
            if(!dir.exists()) {
                System.out.println("您錄入的文件夾路徑不存在,請輸入一個文件夾路徑:");
            }else if(dir.isFile()) {
                System.out.println("您錄入的是文件路徑,請輸入一個文件夾路徑:");
            }else {
                //5,將文件夾路徑對象返回
                return dir;
            }
        }

    }

}

File類遞歸調用(拷貝文件夾)

  • 需求:3,從鍵盤接收兩個文件夾路徑,把其中一個文件夾中(包含內容)拷貝到另一個文件夾中
public class Test3 {

    /**
     * 需求:3,從鍵盤接收兩個文件夾路徑,把其中一個文件夾中(包含內容)拷貝到另一個文件夾中
     * 
     * 把其中一個文件夾中(包含內容)拷貝到另一個文件夾中
     * 分析:
     * 1,在目標文件夾中創建原文件夾
     * 2,獲取原文件夾中所有的文件和文件夾,存儲在File數組中
     * 3,遍歷數組
     * 4,如果是文件就用io流讀寫
     * 5,如果是文件夾就遞歸調用
     * @throws IOException 
     */
    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);
        }
    }
    /*
     * 把其中一個文件夾中(包含內容)拷貝到另一個文件夾中
     * 1,返回值類型void
     * 2,參數列表File src,File dest
     */
    public static void copy(File src, File dest) throws IOException {
        //1,在目標文件夾中創建原文件夾
        File newDir = new File(dest, src.getName());
        newDir.mkdir();
        //2,獲取原文件夾中所有的文件和文件夾,存儲在File數組中
        File[] subFiles = src.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);
            }
        }
    }
}

File類遞歸調用(按層級打印)

  • 需求:4,從鍵盤接收一個文件夾路徑,把文件夾中的所有文件以及文件夾的名字按層級打印, 例如:
    aaa是文件夾,裏面有bbb.txt,ccc.txt,ddd.txt這些文件,有eee這樣的文件夾,eee中有fff.txt和ggg.txt,打印出層級來
public class Test4 {

    /**
     * 需求:4,從鍵盤接收一個文件夾路徑,把文件夾中的所有文件以及文件夾的名字按層級打印, 例如:
     * 把文件夾中的所有文件以及文件夾的名字按層級打印
     * 分析:
     * 1,獲取所有文件和文件夾,返回的File數組
     * 2,遍歷數組
     * 3,無論是文件還是文件夾,都需要直接打印
     * 4,如果是文件夾,遞歸調用
     *  day07
     *      day08
     *          xxx.jpg
     *          yyy.txt
     *      Demo1_Consturctor.class
     *      Demo1_Consturctor.java
     *  Demo1_Student.class
     *  Demo1_Student.java
     */
    public static void main(String[] args) {
        File dir = Test1.getDir();              //獲取文件夾路徑
        printLev(dir,0);
    }

    public static void printLev(File dir,int lev) {
        //1,把文件夾中的所有文件以及文件夾的名字按層級打印
        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);
                printLev(subFile,lev+1);//不可以lev++或者++lev,會破壞lev的值
            }
        }
    }

}

斐波那契數列

  • 不死神兔
  • 故事得從西元1202年說起,話說有一位意大利青年,名叫斐波那契。
  • 在他的一部著作中提出了一個有趣的問題:假設一對剛出生的小兔一個月後就能長成大兔,再過一個月就能生下一對小兔,並且此後每個月都生一對小兔,一年內沒有發生死亡,
  • 問:一對剛出生的兔子,一年內繁殖成多少對兔子?
  • 1 1 2 3 5 8 13
  • 第一個月一對小兔子 1
  • 第二個月一對大兔子 1
  • 第三個月一對大兔子生了一對小兔子 2
  • 第四個月一對大兔子生了一對小兔子
  • 一對小兔子長成大兔子 3
  • 第五個月兩對大兔子生兩對小兔子
  • 一對小兔子長成大兔子 5
    public static void main(String[] args) {
        // demo1();
        System.out.println(fun(8));
    }

    /*
     * 用遞歸求斐波那契數列
     */
    public static int fun(int num) {
        if (num == 1 || num == 2) {
            return 1;
        } else {
            return fun(num - 2) + fun(num - 1);
        }
    }

1000的階乘尾部零的個數(遞歸)

  • 需求:求出1000的階乘尾部零的個數,用遞歸做
    public  int fun(int num) {
        if(num > 0 && num < 5) {
            return 0;
        }else {
            return num / 5 + fun(num / 5);
        }
    }

遞歸的高級使用-漢諾塔問題

前言:如果你跟我一樣,看文章感覺很累的話,那麼可以嘗試一下看這個連小白都可以看得懂的那個參考視頻

參考文章:
1.Hanoi Tower 漢諾塔的簡單分析/C - Geek_Ling - 博客園
2.Java經典編程300例之實例047 漢諾塔問題求解(遞歸) - - 博客頻道 - CSDN.NET

參考視頻:
1.百度網盤鏈接: https://pan.baidu.com/s/1nuEP9CP 密碼: 9ie9

主要代碼:

public class HanoiTower {

    /**
     * 移動盤子
     * topN:移動的盤子數
     * from:起始塔座
     * inter:中間塔座
     * to:目標塔座
     */
    public static void doTower(int topN,char from,char inter,char to) {
        if(topN == 1) {
            System.out.println("盤子1,從"+ from + "塔座到" + to + "塔座");
        } else {
            doTower(topN - 1, from, to, inter);
            System.out.println("盤子" + topN +",從" + from + "塔座到" + to + "塔座" );
            doTower(topN - 1, inter, from, to);
        }
    }
}

測試代碼:

HanoiTower.doTower(3, 'A', 'B', 'C');

運行結果:
這裏寫圖片描述

第三篇複習連接:
Java基礎複習(三) - it菜鳥的飛行夢 - 博客頻道 - CSDN.NET

第三篇複習連接:
Java基礎複習(五) - it菜鳥的飛行夢 - 博客頻道 - CSDN.NET

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章