Java方法遞歸的形式和常見(jiàn)遞歸算法(方法遞歸結(jié)合File類查找文件)
方法遞歸
方法遞歸的形式
什么是方法遞歸?
方法直接調(diào)用自己或者間接調(diào)用自己的形式稱為方法遞歸( recursion)。
遞歸做為一種算法在程序設(shè)計(jì)語(yǔ)言中廣泛應(yīng)用。
遞歸的形式:
直接遞歸:方法自己調(diào)用自己。
public static void main(String[] args) { test(); } // 定義一個(gè)方法 public static void test() { // 直接遞歸方法內(nèi)部調(diào)用自己 test(); }
間接遞歸:方法調(diào)用其他方法,其他方法又回調(diào)方法自己。
public static void main(String[] args) { test1(); } public static void test1 () { // 間接遞歸, 方法內(nèi)部調(diào)用其他方法, 其他方法再調(diào)用此方法 test2(); } private static void test2() { test1(); }
遞歸存在的問(wèn)題?
遞歸如果沒(méi)有控制好終止,會(huì)出現(xiàn)遞歸死循環(huán),導(dǎo)致棧內(nèi)存溢出現(xiàn)象。
遞歸常見(jiàn)的算法
遞歸案例導(dǎo)學(xué)-計(jì)算1-n的階乘:
需求:
計(jì)算1-n的階乘的結(jié)果,使用遞歸思想解決,我們先從數(shù)學(xué)思維上理解遞歸的流程和核心點(diǎn)。分析:
把一個(gè)復(fù)雜的問(wèn)題層層轉(zhuǎn)化為一個(gè)與原問(wèn)題相似的規(guī)模較小的問(wèn)題來(lái)求解。
假如我們認(rèn)為存在一個(gè)公式是 f(n) = 1234567*…(n-1)*n;
那么公式等價(jià)形式就是: f(n) = f(n-1) *n
如果求的是 1-5的階乘 的結(jié)果,我們手工應(yīng)該應(yīng)該如何應(yīng)用上述公式計(jì)算:
f(5) = f(4) * 5
f(4) = f(3) * 4
f(3) = f(2) * 3
f(2) = f(1) * 2
f(1) = 1當(dāng)f(1)時(shí)作為條件退出遞歸
示例代碼:
public static void main(String[] args) { System.out.println(f(5)); } public static int f(int num) { if (num == 1) { return 1; } else { return num * f(num - 1); } }
遞歸案例導(dǎo)學(xué)-計(jì)算1-n的和
需求:
計(jì)算1-n的和的結(jié)果,使用遞歸思想解決,我們先從數(shù)學(xué)思維上理解遞歸的流程和核心點(diǎn)。分析:
假如我們認(rèn)為存在一個(gè)公式是 f(n) = 1 + 2 + 3 + 4 + 5 + 6 + 7 + …(n-1) + n;
那么公式等價(jià)形式就是: f(n) = f(n-1) + n
遞歸的終結(jié)點(diǎn):f(1) = 1
如果求的是 1-5的和 的結(jié)果,應(yīng)該如何計(jì)算。
f(5) = f(4) + 5
f(4) = f(3) + 4
f(3) = f(2) + 3
f(2) = f(1) + 2
f(1) = 1
示例代碼:
public static void main(String[] args) { System.out.println(sum(100)); } public static int sum(int num) { if (num == 1) { return 1; } else { return num + sum(num - 1); } }
案例導(dǎo)學(xué)-猴子吃桃問(wèn)題:
猴子第一天摘下若干桃子,當(dāng)即吃了一半,覺(jué)得好不過(guò)癮,于是又多吃了一個(gè); 第二天又吃了前天剩余桃子數(shù)量的一半,覺(jué)得好不過(guò)癮,于是又多吃了一個(gè); 以后每天都是吃前天剩余桃子數(shù)量的一半,覺(jué)得好不過(guò)癮,又多吃了一個(gè); 等到第10天的時(shí)候發(fā)現(xiàn)桃子只有1個(gè)了。
需求:
請(qǐng)問(wèn)猴子第一天摘了多少個(gè)桃子?分析:
整體來(lái)看,每一天都是做同一個(gè)事件,典型的規(guī)律化問(wèn)題,考慮遞歸三要素:
遞歸公式(例如第一天桃子的總數(shù)用f(n)表示, f(n+1)代表第二天):
f(n) - f(n)/2 - 1 = f(n+1)
變形可得:f(n)= 2f(n+1) + 2
遞歸終結(jié)點(diǎn):f(10) = 1
難點(diǎn): 使用數(shù)學(xué)思想, 推導(dǎo)出遞歸公式
示例代碼:
public static void main(String[] args) { System.out.println(foo(1)); } public static int foo(int n) { if (n == 10) { return 1; } else { return 2 * foo(n + 1) + 2; } }
非規(guī)律遞歸案例
在上述的案例中遞歸算法都是針對(duì)存在規(guī)律化的遞歸問(wèn)題。
有很多問(wèn)題是非規(guī)律化的遞歸問(wèn)題,比如文件搜索。如何解決?
- 非規(guī)律化遞歸問(wèn)題自己看著辦,需要流程化的編程思維。
案例導(dǎo)學(xué)-文件搜索:
需求:
- 從電腦某一路徑下,搜索出某個(gè)文件名稱并輸出絕對(duì)路徑。
分析:
- 先定位出的應(yīng)該是一級(jí)文件對(duì)象
- 遍歷全部一級(jí)文件對(duì)象,判斷是否是文件
- 如果是文件,判斷是否是自己想要的
- 如果是文件夾,需要繼續(xù)遞歸進(jìn)去重復(fù)上述過(guò)程
示例代碼:
public class RecursionDemo5 { public static void main(String[] args) { findFile("demo2.txt", new File("/Users/chenyq/Documents/file_test")); } /** * @param name 搜索的文件名 * @param dir 搜索的目錄 * @return */ public static void findFile(String name, File dir) { // 判斷目錄是否為空 if (dir != null && dir.isDirectory()) { // 獲取目錄下的一級(jí)文件數(shù)組 File[] files = dir.listFiles(); // 判斷數(shù)組是否有內(nèi)容 if (files != null && files.length > 0) { // 不為空則遍歷數(shù)組 for (File file : files) { // 判斷是文件還是文件夾 if (file.isFile()) { // 判斷當(dāng)前文件是否是要查找的文件 if (file.getName().contains(name)) { System.out.println("文件路徑是: " + file.getAbsolutePath()); return; } } else { // 遞歸查找子目錄 findFile(name, file); } } } } else { System.out.println("請(qǐng)輸入正確的目錄!"); } } }
到此這篇關(guān)于Java方法遞歸的形式和常見(jiàn)遞歸算法-方法遞歸結(jié)合File類查找文件的文章就介紹到這了,更多相關(guān)Java方法遞歸和算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)滑動(dòng)驗(yàn)證碼生成(后端工具類)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)滑動(dòng)驗(yàn)證碼生成功能中的后端工具類部分,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-10-10Java Class.forName()用法和newInstance()方法原理解析
這篇文章主要介紹了Java Class.forName()用法和newInstance()方法原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08Java報(bào)錯(cuò):Error:java:?程序包org.springframework.boot不存在解決辦法
建完springboot項(xiàng)目時(shí),點(diǎn)擊啟動(dòng),有可能會(huì)報(bào)錯(cuò),下面這篇文章主要給大家介紹了關(guān)于Java報(bào)錯(cuò):Error:java:?程序包org.springframework.boot不存在的解決辦法,需要的朋友可以參考下2024-02-02IDEA調(diào)試源碼小技巧之辨別抽象類或接口多種實(shí)現(xiàn)類的正確路徑
這篇文章主要介紹了IDEA調(diào)試源碼小技巧之辨別抽象類或接口多種實(shí)現(xiàn)類的正確路徑,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01SpringBoot整合Log4j2實(shí)現(xiàn)自定義日志打印失效的原因及解決
本文給大家介紹了關(guān)于SpringBoot項(xiàng)目整合Log4j2實(shí)現(xiàn)自定義日志打印失效原因及解決辦法,主要的原因是因?yàn)镾pringBoot的logback包的存在,文中通過(guò)圖文給大家了詳細(xì)解決方法,需要的朋友可以參考下2024-01-01Java設(shè)計(jì)模式之狀態(tài)模式State Pattern詳解
這篇文章主要介紹了Java設(shè)計(jì)模式之狀態(tài)模式State Pattern,狀態(tài)模式允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變的時(shí)候改變其行為。這個(gè)對(duì)象看上去就像是改變了它的類一樣2022-11-11