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