【本文概要和说明】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;}复制代码
运行截图:
最后的返回处理需要根据自己的需求进行返回。
【如若文档有错误,欢迎大家不吝赐教。如果发现有侵权等行为,请联系我,我将对应处理,谢谢~~~】