#練習一:從鍵盤接收一個文件夾路徑,統計該文件夾大小
###分析:
####每句話相當與每一個要求,每一個要求用一個方法去實現
第一個方法
* getDir()* 第一個要求:從鍵盤接收一個文件夾路徑* 1,創建鍵盤錄入對象* 2,定義一個無限循環* 3,將鍵盤錄入的結果存儲并封裝成File對象* 4,對File對象判斷* 5,將文件夾路徑對象返回
第二個方法
* getFileLength(File dir),傳入第一個方法所輸入并且經過判斷篩選之后的文件夾路徑File dir* 第二個要求:統計該文件夾大小* 1,定義一個求和變量* 2,獲取該文件夾下所有的文件和文件夾 ListFiles();* 3,遍歷數組* 4,判斷如果是文件,就計算大小并累加* 5,判斷如果是文件夾,就遞歸調用 只有是文件夾才進行遞歸調用,是因為,文件夾大小不能直接獲取,而文件可以直接獲取字節個數
具體代碼如下:
package com.yy.test;import java.io.File;
import java.util.Scanner;public class Test1 {/*** 需求:* 1,從鍵盤接收一個文件夾路徑,統計該文件夾大小* * 第一個方法* getDir()* 第一個要求:從鍵盤接收一個文件夾路徑* 1,創建鍵盤錄入對象* 2,定義一個無限循環* 3,將鍵盤錄入的結果存儲并封裝成File對象* 4,對File對象判斷* 5,將文件夾路徑對象返回* * 第二個方法* getFileLength(File dir),傳入第一個方法所輸入并且經過判斷篩選之后的文件夾路徑File dir* 第二個要求:統計該文件夾大小* 1,定義一個求和變量* 2,獲取該文件夾下所有的文件和文件夾 ListFiles();* 3,遍歷數組* 4,判斷如果是文件,就計算大小并累加* 5,判斷如果是文件夾,就遞歸調用 只有是文件夾才進行遞歸調用,是因為,文件夾大小不能直接獲取,而文件可以直接獲取字節個數* * */public static void main(String[] args) {File dir = getDir(); //調用第一個方法,直接獲取文件夾System.out.println(getFileLength(dir));/*File dir = new File("F:\\wps"); //返回結果為0,也就是不能直接獲取文件夾大小System.out.println(dir.length()); //直接獲取文件夾的結果為0*/}/*** 從鍵盤接收一個文件夾路徑* 方法分析:* 1,返回值類型為File 獲取文件夾路徑,所以返回值類型是File* 2,參數列表無* */public static File getDir(){Scanner wsq = new Scanner(System.in); //創建鍵盤錄入對象System.out.println("請輸入一個文件路徑:"); //輸出一個提示語句while(true){ //定義一個無限循環String line = wsq.nextLine(); //將鍵盤錄入的結果存儲到line里;String nextLine():此掃描器執行當前行,并返回跳過的輸入信息。 此方法返回當前行的其余部分,不包括結尾處的行分隔符。當前位置移至下一行的行首。File dir = new File(line); //并將line封裝成File對象dirif(!dir.exists()){ //對File對象dir,進行判斷,如果錄入的文件夾路徑不存在 ;boolean exists():當且僅當此抽象路徑名表示的文件或目錄存在時,返回 true;否則返回 false System.out.println("您錄入的文件夾路徑不存在,請輸入一個文件夾路徑: "); //給予提示}else if(dir.isFile()){ //對File對象dir,進行判斷,如果錄入的是文件路徑;boolean isFile():當且僅當此抽象路徑名表示的文件存在且 是一個標準文件時,返回 true;否則返回 false System.out.println("您錄入的是文件路徑,請輸入一個文件夾路徑: "); //給予提示}else { //對File對象dir,進行判斷,錄入的是文件夾路徑return dir; //將文件夾路徑對象返回}}}/*** 統計該文件夾大小* 方法分析:* 1,返回值類型long length()方法的返回值是long* 2,參數列表File dir* */public static long getFileLength(File dir){long len = 0; //定義一個求和變量File [] subFiles = dir.listFiles(); //獲取該文件夾下所有的文件和文件夾 ;File[] listFiles():返回一個抽象路徑名數組,這些路徑名表示此抽象路徑名表示的目錄中的文件。for (File subFile : subFiles) { //遍歷數組;使用增強for循環遍歷 if(subFile.isFile()){ //判斷如果是文件len = len + subFile.length(); //就計算大小并累加到求和變量len上}else{ //判斷如果是文件夾len = len + getFileLength(subFile); //就再次調用該方法,進行遞歸調用;不能直接獲取文件夾大小,文件可以直接獲取字節個數}}return len; //最后,返回求和變量len的值}
}
#練習二:從鍵盤接收一個文件夾路徑,刪除該文件夾;(刪除要慎重,因為刪除的內容不經過回收站)
####分析:
*1,獲取該文件夾下的所有的文件和文件夾
*2,遍歷數組
*3,判斷是文件直接刪除
*4,如果是文件夾,遞歸調用
*5,循環結束后,把空文件夾刪掉
package com.yy.test;import java.io.File;public class Test2 {public static void main(String[] args) {File dir = Test1.getDir(); //對方法進行調用,調用Test1里面的getDir()方法,即從鍵盤接收一個文件夾路徑的方法,獲取文件夾路徑deleteFile(dir);}/**、* 刪除文件夾* 方法分析* 1,返回值類型void 因為刪除嘛,不需要任何的返回,直接刪掉就可以了* 2,參數列表File dir* */public static void deleteFile(File dir){File [] subFiles = dir.listFiles(); //獲取該文件夾下的所有的文件和文件夾 listFiles():返回一個抽象路徑名數組,這些路徑名表示此抽象路徑名表示的目錄中的文件for (File subFile : subFiles) { //遍歷數組if(subFile.isFile()){ //判斷是文件subFile.delete(); //直接刪除}else{ //判斷是文件夾deleteFile(subFile); //遞歸調用}}dir.delete(); //循環結束后,把空文件夾刪掉;若不加這個,只會把文件給刪掉,而不會把文件夾給刪掉,會留有空文件夾}}
#練習三:從鍵盤接收兩個文件夾路徑,把其中一個文件夾中(包含內容)拷貝到另一個文件夾中
###例如,第一次錄入的文件夾路徑是 F:\wsq ,第二個錄入的文件夾路徑是 F:\yy
運行結束之后,就是在 F:\yy 該路徑下重新將 wsq 文件夾全部拷貝下來;
###F:\yy\wsq,其中yy是父級路徑,wsq是子級路徑
分析:
- 1,在目標文件夾中創建原文件夾 原文件夾 原文件夾
- 2,獲取原文件夾中所有的文件和文件夾,存儲在File數組中
- 3,遍歷數組
- 4,如果是文件就用IO流讀寫 IO流只能讀寫文件不能讀取文件夾
- 5,如果是文件夾,就遞歸調用
package com.yy.test;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class Test3 {
/*** @throws IOException * */public static void main(String[] args) throws IOException {File wsq = Test1.getDir();File yy = Test1.getDir();if(wsq.equals(yy)){System.out.println("目標文件夾是原文件夾的子文件夾");}else{copy(wsq,yy);}}
/*** 把其中一個文件夾中(包含內容)拷貝到另一個文件夾中* 1,返回值類型void* 2,參數類型File wsq(原),File yy()* @throws IOException * * */
private static void copy(File wsq, File yy) throws IOException {File newDir = new File(yy,wsq.getName()); //在目標文件夾中創建原文件夾// getName():返回由此抽象路徑名表示的文件或目錄的名稱// mkdirs():創建此抽象路徑名指定的目錄,包括所有必需但不存在的父目錄;當且僅當已創建目錄以及所有必需的父目錄時,返回 true;否則返回 false newDir.mkdir(); //這一步驟完成之后,就相當于在yy文件夾下創建wsq文件File [] subFiles = wsq.listFiles(); //獲取原文件夾(wsq)下的所有的文件和文件夾,存儲在File數組中for (File subFile : subFiles) { //遍歷數組;if(subFile.isFile()){ //如果是 文件 ,就用IO流(字節流)讀寫BufferedInputStream bis = new BufferedInputStream(new FileInputStream(subFile)); //輸入流;字符流只能拷貝文本,拷貝文件可以是任意的文件,不止是拷貝文本,所以說,只能用字節流,不能用字符流BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(newDir,subFile.getName()))); //輸出流;getName():返回由此抽象路徑名表示的文件或目錄的名稱int b;while((b = bis.read()) != -1){bos.write(b);}bis.close(); //關流bos.close(); //關流}else{ //如果是 文件夾 ,就遞歸調用copy(subFile,newDir);}}}}
#練習四:從鍵盤接收一個文件夾路徑,把文件夾中的所有文件以及文件夾的名字按層級打印
分析:
- 1,獲取所有文件和文件夾,返回的File數組
- 2,遍歷數組
- 3.無論是文件還是文件夾,都需要直接打印
- 4,如果是文件夾,遞歸調用
package com.yy.test;import java.io.File;public class Test4 {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.println("\t");}//3.無論是文件還是文件夾,都需要直接打印System.out.println(subFile);//4,如果是文件夾,遞歸調用if(subFile.isDirectory()){printLev(subFile,lev + 1);}}}
}
#練習五:斐波那契數列(數組求跟遞歸求兩種方法)
package com.yy.test;public class Test5 {/*** 不死神兔* 故事得從西元1202年說起,話說有一位意大利青年,名叫斐波那契。* 在他的一部著作中提出了一個有趣的問題:假設一對剛出生的小兔,一個月后就能長成大兔,再過一個月就能生下一對小兔,并且此后每個月都生下一對小兔* 問:一對剛出生的兔子,一年內繁殖成多少對兔子?* 1 1 2 3 5 8 13 21 34 ...... * * * */public static void main(String[] args) {
// demo1(); //用數列求,不用遞推System.out.println(fun(22)); //調用遞歸方法求}private static void demo1() {//用數組做不死神兔int [] arr = new int [10];//數組中第一個元素和第二個元素都為1arr[0] = 1;arr[1] = 1;//遍歷數組對其他元素賦值for (int i = 2; i < arr.length; i++) {arr [i] = arr[i-2] + arr[i-1];}/*//可以提供循環,全部打印出來for (int i = 0; i < arr.length; i++) {System.err.println(arr[i]);}*/System.out.println(arr.length-1); //也可以只打印最后一個月,兔子的對數}/*** 用遞歸來求斐波那契數列* */public static int fun(int num){if(num == 1 || num == 2){return 1;}else {return fun(num - 1) + fun(num - 2);}}
}
##練習六:斐波那契數列(數組求跟遞歸求兩種方法)
###①求出1000!所有零的個數,不用遞歸
package com.yy.test;import java.math.BigInteger;public class Test6 {
/*** 需求:求出1000!所有零的個數,不用遞歸* * * */public static void main(String[] args) {/*int result = 1;for (int i = 0; i <= 1000; i++) {result = result * i;}System.out.println(result); //最后的輸出結果為0,因為1000!遠大于int的取值范圍,所以輸出最后的結果為0*/demo1();demo2();}private static void demo2() { //獲取1000!尾部有多少個零BigInteger bi1 = new BigInteger("1");for (int i = 1; i <= 1000; i++) {BigInteger bi2 = new BigInteger(i + "");bi1 = bi1.multiply(bi2); //將bi1與bi2相乘的結果賦值給bi1}String str = bi1.toString(); //獲取字符串表現形式StringBuilder sb = new StringBuilder(str);str = sb.reverse().toString(); //鏈式編程int count = 0; //定義計數器for (int i = 0; i < str.length(); i++) {if('0' != str.charAt(i)){break;}else{count ++;}}System.out.println(count);
}private static void demo1() { //求1000!中所有的零BigInteger bi1 = new BigInteger("1");for (int i = 1; i <= 1000; i++) {BigInteger bi2 = new BigInteger(i + "");bi1 = bi1.multiply(bi2); //將bi1與bi2相乘的結果賦值給bi1}System.out.println(bi1);String str = bi1.toString(); //獲取字符串表現形式int count = 0;for(int i = 0; i <str.length(); i ++){if('0' == str.charAt(i)){count ++;}}System.out.println(count);
}}
###②求出1000!所有零的個數,用遞歸
/*** 需求:求出1000!尾部零的個數,用遞歸做* 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 * 5 5 * 5 * 2 5 * 5 * 3 5 * 5 * 4 5 * 5 * 5 5 * 5 * 6 200/5=40* 5 * 5 * 5 * 1 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* 5 * 5 * 5 * 5 * 5 8/5=1 * 200+40+8+1=249* */
package com.yy.test;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);}}
}
練習七:約瑟夫環
故事:從前有個叫約瑟夫環的國王,國王有一天很高興,就把監獄里面的500個死囚犯帶出來,說:“你們開始排隊,從1開始以此報數,若是3的倍數就直接拉出去給殺掉,最后剩余1個人,無罪釋放。”
問題:鍵盤輸入人數,然后進排序,從1開始以此報數,若是3的倍數的人會被殺掉,后面的人接著報數。
例如:10個人
1 2 3 4 5 6 7 8 9 10
11 12 被殺 13 14 被殺 15 16 被殺 17
18 被殺 19 20 被殺 21 22
被殺 23 24 被殺 25
26 被殺 27
28 被殺
最后只有一個人生還,就是 4。
package com.yy.test;import java.util.ArrayList;public class Test8 {public static void main(String[] args) {System.out.println(getLuckluNum(8));}
/*** 獲取幸運數字* 1,返回值類型int* 2,參數列表int num* * */public static int getLuckluNum(int num){ArrayList<Integer> list = new ArrayList<>(); //創建集合存儲1到num對象for (int i = 1; i <= num; i++) { //將1到num存儲在集合中 list.add(i); }int count = 1; //用來數數的,只要是3的倍數就殺人for (int i = 0; list.size() != 1; i++) { //只要集合中人數超過1,就要不斷地殺if(i == list.size()){ //如果i增長到集合最大的索引+1時i = 0; //重新歸零}if(count % 3 == 0){ //如果是3的倍數就殺人list.remove(i--);}count++;}return list.get(0);}
}