PHP递归经典算法实例

    科技2022-08-03  92

    PHP 递归经典算法实例

    排列算法

    首先明确函数的输入和输出,输入是一个字符串还有排列的个数,输出用数组来表示,所以函数的雏形应该是这样的

    function permutation($str, $len) { $res = []; if ($len == 1) { $res = str_split($str); } else { //todo } return $res; }

    接着进行第二步,假设我们已经知道了len-1的输出,要由这个输出得出len的输出。在这个问题里,如果我已经知道了“abcd”选取2个的输出的集合,现在要“abcd”的选取3个集合,要怎样得出呢?

    不难发现“abcd”选取1个的结果(a,b,c,d),与“abcd”选取2个的结果(ab,ac,ad,ba,bc,bd,…)的关系,在(a,b,c,d)后面循环插入单个元素与“abcd”的差集。于是得到如下算法。

    function permutation($str, $len) { $res = []; if ($len == 1) { $res = str_split($str); } else { $list = permutation($str, $len - 1); foreach ($list as $vo) { $_arr = array_diff(str_split($str), str_split($vo)); foreach ($_arr as $item) { $res[] = $vo . $item; } } } return $res; } //测试结果 echo PHP_EOL . '<==排列==>' . PHP_EOL; $res = permutation('abcd', 2); print_r($res);

    组合算法

    组合与排列类似,在插入元素时索引必须大于原来集合的任意一个元素的索引

    function combination($str, $len) { $res = []; if ($len == 1) { $res = str_split($str); } else { $list = combination($str, $len - 1); foreach ($list as $vo) { $_arr = array_diff(str_split($str), str_split($vo)); $index1 = strpos($str, substr($vo, -1, 1)); foreach ($_arr as $item) { $index2 = strpos($str, $item); //在插入元素$item时索引必须大于原来集合的任意一个元素的索引 if ($index2 > $index1) $res[] = $vo . $item; } } } return $res; } echo PHP_EOL . '<==组合==>' . PHP_EOL; $res = combination('abcd', 2); print_r($res); function combination($arr,&$res ,$len,$temp_arr=array()) { $arr_len = count($arr); if ($len == 0) { $res[] = $temp_arr; } else { for ($i = 0; $i < $arr_len - $len + 1; $i++) { $tmp = array_shift($arr); $temp_arr[] = $tmp; combination($arr, $res,$len - 1, $temp_arr); array_pop($temp_arr); } } } echo PHP_EOL . '<==组合算法2==>' . PHP_EOL; combination(['a','b','c'],$re,2); print_r([$re]);

    最大公约数

    /* * 更相减损术 求取最大公约数 */ function get_GCD($a, $b) { if (is_int($a) && is_int($b) && $a > 0 && $b > 0) { if ($a == $b) { return $a; } else if ($a < $b) { return get_GCD($a, $b - $a); } else { return get_GCD($b, $a - $b); } } return NULL; } $res = get_GCD(98, 28); var_dump($res); /** * 欧几里得算法 求解最大公约数 * @param $a * @param $b * @return null */ function get_GCD_NUM($a, $b) { if (is_int($a) && is_int($b) && $a > 0 && $b >= 0) { if ($b == 0) { return $a; } else if ($a > $b) { return get_GCD_NUM($b, $a % $b); } else if ($a <= $b) { return get_GCD_NUM($a, $b % $a); } } return NULL; } $a = get_GCD_NUM(98, 28); var_dump($a);

    无限极分类

    function toTree($arr, $pid, $deep = 0) { $tree = []; foreach ($arr as $vo) { if ($vo['pid'] == $pid) { $temp_str = str_repeat(' ', $deep); echo $temp_str . ($deep > 0 ? '└─' : '') . $vo['id'] . PHP_EOL; $temp = toTree($arr, $vo['id'], $deep + 1); if (count($temp) > 0) $vo['children'] = $temp; $tree[$vo['id']] = $vo; } } return $tree; } function toTreeStr($arr, $pid, $deep = 0) { $str = ""; foreach ($arr as $vo) { if ($vo['pid'] == $pid) { $temp_str = str_repeat(' ', $deep); $tmp = $temp_str . ($deep > 0 ? '└─' : '') . $vo['id'] . PHP_EOL; $str .= $tmp; $temp = toTreeStr($arr, $vo['id'], $deep + 1); if ($temp) { $str .= $temp; } } } return $str; } $arr = [ ['id' => 1, 'pid' => 0], ['id' => 9, 'pid' => 2], ['id' => 2, 'pid' => 1], ['id' => 3, 'pid' => 0], ['id' => 4, 'pid' => 2], ['id' => 5, 'pid' => 0], ['id' => 6, 'pid' => 4], ['id' => 7, 'pid' => 5], ['id' => 8, 'pid' => 2], ['id' => 10, 'pid' => 9] ]; $tree = toTree($arr, 0); var_dump($tree); $tree = toTreeStr($arr, 0); var_dump($tree);

    正整数划分问题

    /** * 整数划分问题 * @param $n 整数值 * @param $m 最大加数 */ function splitNum($n,$m){ if($n<=0||$m<=0||!is_int($sn)||!is_int($sn)) return 0; if($n==1||$m==1) return 1; else if($n===$m) return splitNum($n,$n-1)+1; else if($n<$m) return splitNum($n,$n); else return splitNum($n-$m,$m)+splitNum($n,$m-1); } echo splitNum(9,5);

    二叉树

    class TreeNode { /** * @var mixed */ private $value; /** * @var TreeNode */ private $left; /** * @var TreeNode */ private $right; public function __construct($value) { $this->value = $value; return $this; } /** * @return mixed */ public function getValue() { return $this->value; } /** * @param mixed $value * @return TreeNode */ public function setValue($value) { $this->value = $value; return $this; } /** * @return TreeNode */ public function getLeft() { return $this->left; } /** * @param TreeNode $left * @return TreeNode */ public function setLeft(TreeNode $left) { $this->left = $left; return $this; } /** * @return TreeNode */ public function getRight() { return $this->right; } /** * @param TreeNode $right * @return TreeNode */ public function setRight(TreeNode $right) { $this->right = $right; return $this; } } class Tree { /** * @param $root TreeNode * @param int $deep */ public function echoEachNode(TreeNode $root, $deep = 0) { if ($root != null) { $temp_str = str_repeat(' ', $deep); echo $temp_str . ($deep > 0 ? '└─' : '') . $root->getValue() . PHP_EOL; $_deep = $deep + 1; if ($root->getLeft() != null) { $this->echoEachNode($root->getLeft(), $_deep); } if ($root->getRight() != null) { $this->echoEachNode($root->getRight(), $_deep); } } } } //测试 $a = new TreeNode('A'); $b = new TreeNode("B"); $c = new TreeNode("C"); $d = new TreeNode("D"); $e = new TreeNode("E"); $f = new TreeNode("F"); $a->setLeft($b)->setRight($c); $b->setRight($c); $c->setLeft($f); $bst = new Tree(); $bst->echoEachNode($a);
    Processed: 0.014, SQL: 8