【本文概要和說明】
1、簡要說明遞迴演算法
2、例項說明和演示
(本文采用 PHP 語言在CI框架下進行編寫和說明)
【⚠️:文中使用的表述和說明,僅代表個人觀點和理解來書寫,非正式官方解釋】
複製程式碼
一、什麼是遞迴演算法
遞迴:就是指函式呼叫自身的方法。
二、理解和注意事項(要素)
理解:
呼叫自身,其實就是說邏輯和最外層的函式實現是一樣的,我們可以理解為在外層函式執行到某一點時,邏輯就會和外層函式一樣,即:每一次呼叫都是將大問題化解成規模較小的問題進行解決。
我們的使用遞迴的目的是為了實現某個功能,所以我們應該有停止遞迴的條件,然後將遞迴結果返回作為功能實現的資料資訊,我們就需要有一個條件可以停止遞迴,停止之後需要根據功能的需求做對應的邏輯處理。
要素:
1、需要提取出重複的邏輯,為遞迴做好準備。
2、需要一個停止遞迴的條件節點,防止無限遞迴。
3、需要給出停止遞迴後的實現方式,根據需求結果而定。
三、例項說明
1、我們先用幾個簡單的例子理解一下遞迴。
案例一:求 n 的階乘
分析:我們知道階乘的表示式為 n! = 1 * 2 * 3 * ... * n
我們先以 5 的階乘為例:
1! = 1 --------------------------- 1 --------- 1
2! = 2 * 1 ------------------------ 2 * 1! ----- 2 * (2 - 1)!
3! = 3 * 2 * 1 --------------------- 3 * 2! ----- 3 * (3 - 1)!
4! = 4 * 3 * 2 * 1 ------------------ 4 * 3! ----- 4 * (4 - 1)!
5! = 5 * 4 * 3 * 2 * 1 --------------- 5 * 4! ----- 5 * (5 - 1)!
... ... ... ... ... ... ... ... ...
n! = n * (n - 1)!
我們用常規方法實現階乘,程式碼如下:
public function factorial_normal($num)
{
$n = 1;
$result = 1;
while($n <= $num){
$result *= $n;
$n ++;
}
return $result;
}
複製程式碼
我們用遞迴方式實現階乘,程式碼如下:
public function factorial_recursive($num)
{
if($num == 1)
{
return 1;
}
$result = $num * $this->factorial_recursive($num - 1);
return $result;
}
複製程式碼
案例二:給定一個關鍵字,將陣列中包含該關鍵字的 key 對應的 value 前都加上一個標記 ‘Mark:’。
// 遍歷陣列,找出給定陣列中所有指定 key 的值,並新增 Mark 標記
public function deepLoop(&$arr, $keyword = '')
{
// 設定匹配正規表示式
$reg = "/" . $keyword . "/i";
// 判斷陣列和關鍵字的有效性
if( ! is_array($arr) || $keyword == '' || $keyword == null)
{
return $arr;
}
// 迴圈陣列,找出指定的 key, 並給對應的值加上 Mark 標記
foreach($arr as $key => $value)
{
if(is_array($value))
{
$this->deepLoop($value, $keyword);
}
else
{
if(preg_match($reg, $key))
{
$value = 'Mark: ' . strval($value);
}
}
$arr[$key] = $value;
}
return $arr;
}
複製程式碼
除錯(我們執行 $this->deepLoop($userInfo, 'name');
):
我們首先使用一維陣列:
$userInfo = [
'userName' => 'user1',
'userAge' => 18,
'testName' => 'user test name'
];
複製程式碼
執行截圖:
多維陣列:
$userInfo = [
'userName' => 'user1',
'userAge' => 18,
'testName' => 'user test name',
'child' => [
'userName' => 'user1',
'userAge' => 18,
'testName' => 'user test name',
'child' => [
[
'userName' => 'user1',
'userAge' => 18,
'testName' => 'user test name'
],
[
'userName' => 'user1',
'userAge' => 18,
'testName' => 'user test name'
]
]
]
];
複製程式碼
執行截圖:
案例三:列印出指定路徑下的目錄結構
分析:
1、我們首先需要知道該目錄下有些什麼東西(資料夾和檔案)
2、要對目錄下的東西進行分類處理
實現程式碼:
public function dirLoop($path, &$treeData = [])
{
// 判斷給定的 path 是否是一個正確的路徑
if( ! is_dir($path))
{
return $path;
}
$docList = scandir($path);
$reg = '/^\.[\w]+$/';
foreach($docList as $key => $doc)
{
if($doc == '.' || $doc == '..' || preg_match($reg, $doc))
{
continue;
}
else
{
$newPath = $path . '/' . $doc;
if(is_dir($newPath))
{
$treeData[$path][$newPath] = [];
$this->dirLoop($newPath, $treeData[$path]);
}
else
{
$treeData[$path][$newPath] = 'f';
}
}
}
return $treeData;
}
複製程式碼
執行截圖:
最後的返回處理需要根據自己的需求進行返回。
【如若文件有錯誤,歡迎大家不吝賜教。如果發現有侵權等行為,請聯絡我,我將對應處理,謝謝~~~】