Java遞歸紀要

package cn.dg;
/**
 * 哈嘍,大家好!
 * 今天講一下Java中的遞歸;
 * 
 * 遞歸
 * 所謂的遞歸:就是是自己調用自己;
 * 當然我們不能讓自己的程序一直這樣重複下去,因此遞歸使用時一定要注意它的規則邊界;
 * 
 * 遞歸分類:
 * 接下來聊一下遞歸常見的表現形式;
 * 一般我們對於遞歸的應用無非就兩種情況:
 * 	1. 自己調用自己;(直接遞歸)
 * 	2. A,B,N+ 回調 A,B,N+;(間接遞歸)
 * 我們稱第一種自己調用自己的這種遞歸方式爲常用的直接遞歸;
 * 而第二種大型遞歸方式稱爲間接遞歸;
 * 
 * 規則邊界:
 * 	1. 構造方法不能遞歸;(構造器是用來創建對象的,因而不能讓這種消耗型動作持續的去創建對象)
 * 	2. 遞歸運算在設計過程中一定要有作爲出口的終止限定條件;(死循環會造成棧內存溢出)
 * 	3. 同樣,設計遞歸運算時一定要考慮到遞歸實際佔用內存的問題,要對遞歸的次數添加限定;
 * 		(如果還沒有執行到跳出遞歸的條件約束,JVM內存就用光,也會報棧內存溢出;)
 * 
 * 好,還是和以前一樣;
 * 首先創建一個自己的測試類;
 * @author TANJIYUAN
 */
public class DgTest {

	/**
	 * 創建一個計算1~n位數字之和的方法;
	 * 實現:
	 * 		1+2+3+n...
	 * 		x+(x+1)|x+(++x); -> 1+(1+1) -> 1+2
	 * 		x+(x+1)|x+(++x); -> 2+(2+1) -> 2+3
	 * 		x+(x+1)|x+(++x); -> ...
	 * 在程序中實現可以把第二步2+3的缺值通過補足的方式來彌補;ok;
	 * 那清晰了思路,實現起來就相對easy;Let's go...
	 * 
	 * 
	 * 在goon(int num)這個方法中:
	 * 所實現的方法是限制基數重大大小遞減的方式(當然也可以使用由小到大的方式);實現;
	 * 
	 * @param num
	 * @return
	 */
	public static int goon(Integer num) {
		
		/**
		 * 首先判斷一種特殊情況:
		 * 我們的方法設計開始的規則是:計算1以上的相加數之和;
		 * 那麼也就說如果是1本身,那無需計算;
		 * 那麼在這裏直接做返回處理即可;
		 */
		if(num == 1) {
			return 1;
		}
		
		/**
		 * 如果用戶輸入的數字是負數或者0;計算沒有多大意義;
		 * 所以直接將這種情況作爲出口項進行設計;
		 */
		if(num <= 0) {
			return 0;
		}

		/**
		 * 如果用戶傳入的參數過大,超出運行內存的大小;
		 * 在這裏是需要作爲出口項控制一下的;
		 */
		if(num >= 500) {
			return 0;
		}
		
		/**
		 * 這個地方呢要詳細的說一下:
		 * 如非大牛之輩恐難以直觀;
		 * 我們通過一開始的設計分析發現;其實每次的數據計算都有一個公式x+(++x);
		 * 那麼這個公式所缺的無非就是上一次計算的數據;
		 * 
		 * 這一點我們可以直接通過回調賦值的方式來彌補;(這是我個人對遞歸方式調用的稱謂)
		 * 
		 * 那麼num-1是什麼呢?
		 * 此處想了n久,從小打到的設計思路實現代碼會略微繁瑣,故而採用了這種方式;
		 * 在方法調用的初期,調用者會預傳一個int類型的參數進來,我需要做的無非就是
		 * 判斷1以外的情況;以及對數據進行計算即可;
		 * 因此既然是相加之數,從小到大相加也是一個值;從大到小相加也是一個值,(恰巧用戶輸入的就是
		 * 一個大值)因此,果斷採用的從大到小的方式,每次直接用傳進來的參數計算即可,都不用處理;
		 * 到這裏,相信各位已經有所瞭解這裏面的運行機制;
		 * 
		 * 
		 * 最後呢說一下關於這次遞歸的兩個關鍵性要素在哪裏;
		 * 我們知道:遞歸的設計使用時一定要有規則邊界的,否則必然會陷入死循環中;
		 * 因此我們這次的設計實現也不例外,那麼下面就來說明一下這其中的規則邊界;
		 * 
		 * 首先遞歸的設計一定要有出口,那麼我們的一開始的時候處理1和<=0以及>=500這種情況時,就是出口設計;
		 * 其中的>=500則是根據佔用情況而設計的出口項;
		 */
		return num + goon(num-1);
	}
	
	/**
	 * 程序的入口|主函數;
	 * @param args
	 */
	public static void main(String[] args) {
		
		/**
		 * 然後在這裏調用;傳入一個int類型的參數5來進行計算;
		 * 最終得出15的結果;
		 * 爲了驗證這個結果的正確性,我拿來了公司唯一的一臺認不出牌子的計算器來進行驗證;
		 * 最終得出...它是正確答案;
		 * 那麼至此,關於Java中遞歸的一些小細節就算是告一段落了;
		 * 
		 * 這個例子很多的地方都有引用到,我其實有想用其他的案例來帶過;
		 * 但是小腦瓜還沒開竅,一時間呢也沒有更加舒心的案例來給大家說明;
		 * 所以就將就一下以此爲例,來進行我們Java遞歸的案例說明;
		 */
		System.out.println(goon(5));
	}
}
package cn.dg;

/**
 * 對了,在這裏再給大家給一個關於階乘計算的Demo;
 * 在開始之前大家先了解一下關於階乘的內容;
 * 首先什麼是階乘?
 * 		1. 階乘是基斯頓·卡曼(Christian Kramp,1760~1826)於 1808 年發明的運算符號,是數學術語;
 * 		2. 一個正整數的階乘(factorial)是所有小於及等於該數的正整數的積,並且0的階乘爲1;
 * 		3. 自然數n的階乘寫作n!;
 * 		4. 寫作:n!=1×2×3×...×(n-1)×n;
 * 		5. 那麼用遞歸實現:0!=1,n!=(n-1)!×n;(其中0!=1就表示0的階乘爲1;)
 * 
 * 好了,清晰了階乘的原理,那下面就給大家列出關於階乘利用遞歸方式實現的Demo;
 * 
 * 首先還是和以前一樣,我們先創建一個自己的測試類;
 * @author Administrator
 *
 */
public class DgTest {
	
	/**
	 * 將階乘處理的代碼封裝入一個方法中;
	 * 進行迭代機制的處理;
	 * @param num
	 * @return
	 */
	public static int goon(Integer num) {
		
		/**
		 * 那麼還是和之前一樣;要進行出口項的設置;
		 * 如果參數<0的話沒有計算的必要;因此將其設置爲一項出口項處理;
		 */
		if(num < 0) {
			return 0;
		}
		
		/**
		 * 在設計的時候很容易忘記這塊的設計;
		 * 我們只顧着遞減了,沒有添加對應的限制,如果成0之後任何數相乘都等於0;
		 * 因此也要將此項當作一個出口項處理;
		 */
		if(num == 1) {
			return 1;
		}
		
		/*
		 * 好,那到了最後就是我們的計算工作;
		 * 直接利用我們之前分析好的公式將其帶入即可;
		 */
		return num * goon(num-1);
	}
	
	/**
	 * 程序入口|主函數;
	 * @param args
	 */
	public static void main(String[] args) {
		
		/**
		 * 在這裏進行封裝好迭代方法的調用;
		 * 我們還是傳入一個5的參數;
		 * 還是和之前一樣,我準備了一個陳舊但精準的計算器,進行了結果驗證;
		 * 最終的結論:它是對的;
		 */
		System.out.println(goon(5));
	}
	
}
package cn.dg;

import java.io.File;

/**
 * 下面再列一個文件獲取的迭代Demo;
 * 
 * 創建一個自己的測試類;
 * @author Administrator
 *
 */
public class DgTest {
	
	/**
	 * 封裝對應的迭代機制;
	 * @param file: 方法需要傳入一個文件對象;
	 */
	public static void goonFile(File file) {
		
		/**
		 * 通過文件對象獲取該對象目錄下的所有File目錄對象;
		 * 以數組形式返回;
		 */
		File [] listFile = file.listFiles(); 
		
		/**
		 * 循環數組;
		 */
		for(File thisFile : listFile) {
			
			/**
			 * 出口項;
			 * 
			 * isFile();
			 * 判斷是否爲文件;
			 */
			if(thisFile.isFile()){
				
				/**
				 * getName();
				 * 打印文件的文件名;
				 * 
				 * getAbsolutePath();
				 * 返回文件的絕對路徑;
				 */
				System.out.println(thisFile.getName() + ": " + thisFile.getAbsolutePath());
			}
			
			/**
			 * isDirectory();
			 * 判斷是否爲文件夾;
			 */
			if(thisFile.isDirectory()) {
				goonFile(thisFile);
			}
		}
	}
	
	/**
	 * 程序入口|主函數;
	 * @param args
	 */
	public static void main(String[] args) {
		
		/**
		 * 初始化一個地址參數;
		 */
		String path = "D:\\Software\\JDK";
		
		/**
		 * 實例化文件對象;
		 * 傳入初始化的地址參數;
		 */
		File file = new File (path);
		
		/**
		 * 調用封裝好的方法;
		 */
		goonFile(file);
	}
	
}

 

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