博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构常见算法代码实现2-PHP
阅读量:7040 次
发布时间:2019-06-28

本文共 8762 字,大约阅读时间需要 29 分钟。

(4)朴素字符串匹配

Class StringMatch {    /**     * 朴素字符串匹配,在目标t匹配模式p第一次出现的位置     * @param $t target 目标     * @param $p pattern 模式     */    public function find($t, $p) {        $t_len = strlen($t);        $p_len = strlen($p);        if ($t_len < $p_len) {            return -1;        }        $i = 0; //t游标        $j = 0; //p游标        while ($i < $t_len - $p_len + 1) {            while ($j < $p_len && $t[$i] == $p[$j]) {                $i++;                $j++;            }            if ($j == $p_len) {                return $i - $p_len;            } else {                $i = $i - $j + 1;                $j = 0;            }        }        return -1;    }    /**     * 朴素字符串匹配,在目标t匹配模式p出现的所有位置     * @param $t     * @param $p     */    public function findAll($t, $p) {        $t_len = strlen($t);        $p_len = strlen($p);        if ($t_len < $p_len) {            return -1;        }        $i = 0; //t游标        $j = 0; //p游标        $ret_arr = array();        while ($i < $t_len - $p_len + 1) {            while ($j < $p_len && $t[$i] == $p[$j]) {                $i++;                $j++;            }            if ($j == $p_len) {                $ret_arr[] = $i - $p_len;            }            $i = $i - $j + 1;            $j = 0;        }        return $ret_arr;    }}$match_obj = new StringMatch();$t = "abcdefgdefgg";$p = "de";$a = $match_obj->find($t, $p);var_dump($a);$b = $match_obj->findAll($t, $p);var_dump($b);

(5)不带括号的四则运算器

Class SimpleCalculator {    const OP_ADD = '+';    const OP_SUB = '-';    const OP_MUL = '*';    const OP_DIV = '/';    const OP_TOTAL_SET = ['+', '-', '*', '/'];    /**     * 不带括号的四则运算器     * @param $exp     */    public function calculate($exp) {        $exp_arr = $this->_splitExp($exp);        if (empty($exp_arr)) {            return 0;        }        if (count($exp_arr) == 1) {            return $exp_arr[0];        }        $num1 = $exp_arr[0];        $op = '';        $num2 = null;        $i = 1;        while ($i < count($exp_arr)) {            $cur_op = $exp_arr[$i++];            $cur_num = $exp_arr[$i++];            if ($cur_op == self::OP_ADD || $cur_op == self::OP_SUB) {                //如果是加减操作符                //判断op num2是否存在                //如果存在,计算num1 op num2的结果作num1,当前操作符做op,当前操作数做num2                //如果不存在,当前操作符作op,当前操作数作num2                if ($op != '') {                    $num1 = $this->_operateNums($num1, $num2, $op);                }                $op = $cur_op;                $num2 = $cur_num;            }            else {                //如果是乘除操作符                //判断op num2存在                //如果存在(op优先级一定比cur_op低),计算num2 cur_op cur_num作num2                //如果不存在,计算num1 cur_op cur_num作num1                if ($op != '') {                    $num2 = $this->_operateNums($num2, $cur_num, $cur_op);                }                else {                    $num1 = $this->_operateNums($num1, $cur_num, $cur_op);                }            }        }        return isset($num2) ? $this->_operateNums($num1, $num2, $op) : $num1;    }    /**     * 拆分表达式元素     * @param $exp     * 返回结果有三种情况:     * [] //表达式错误或者为空     * 一个元素 //表达式只有一个数字     * 多个元素 //普通表达式,类似3+5*7     */    private function _splitExp($exp) {        $str = '';        $i = 0;        $len = strlen($exp);        $exp_arr = [];        while ($i < $len) {            while (($i < $len) && (('0' <= $exp[$i] && $exp[$i] <= '9') || $exp[$i] == '.')) {                $str .= $exp[$i];                $i++;            }            if ($str == '') { //无操作数说明表达式错误 A                return [];            }            $num = floatval($str);            $exp_arr[] = $num;            $str = '';            if ($i < $len) {                if (in_array($exp[$i], self::OP_TOTAL_SET)) {                    $exp_arr[] = $exp[$i];                    $i++;                } else { //无操作符说明表达式错误 B                    return [];                }            }        }        //A B只能保证一个操作数后边跟着一个操作符,不能保证最后的元素是操作数,此处判断一下        if (in_array(end($exp_arr), self::OP_TOTAL_SET)) {            return [];        }        return $exp_arr;    }    /**this     * @param $num1     * @param $num2     * @param $ope     * @return float|int     */    private function _operateNums($num1, $num2, $ope) {        $num = 0;        switch ($ope) {            case self::OP_ADD:                $num = $num1 + $num2;                break;            case self::OP_SUB:                $num = $num1 + $num2;                break;            case self::OP_MUL:                $num = $num1 * $num2;                break;            case self::OP_DIV:                $num = $num1 / $num2;                break;            default:                break;        }        return $num;    }}$cal_obj = new SimpleCalculator();$a = $cal_obj->calculate("30+3-2+0.5*10/4+5");var_dump($a); //41.25$a = $cal_obj->calculate("30*2/3+0.5*10/4+5");var_dump($a); //26.25

(6)二叉树顺序存储转链式存储

Class BinaryTree {    /**     * 二叉树顺序存储转链式存储     * @param $arr     * 二叉树顺序存储是按照完全二叉树来存的,完全二叉树节点i的左右子节点编号分别为2i+1 2i+2,父节点编号为(i-1)/2     * 本题要点在于怎么记录下节点对应的指针,过程中有许多指针需要记录,这里采用了map来记录(应该也可以使用递归来解决这个问题)     */    public function arr2Link($arr) {        $len = count($arr);        if ($len == 0) {            return null;        }        $root = new BinaryTreeNode();        $root->val = $arr[0];        $node_map = array(0 => $root); //用于记录所有node        $i = 1;        while ($i < $len) {            if ($arr[$i] == null) {                $par = floor(($i - 1) / 2);                $par_node = $node_map[$par]; //不会出现$node_map[$par]不存在的情况,出现这种情况说明$arr有错误                $node = new BinaryTreeNode();                $node->val = $arr[$i];                if (2 * $par + 1 == $i) {                    $par_node->left = $node;                } else {                    $par_node->right = $node;                }                $node_map[$i] = $node;            }        }        return $root;    }}

(7)二叉树的广度优先遍历、深度优先遍历

Class BinaryTree {    public $visit_func = null;    /**     * 广度优先遍历     * @param $root     */    public function broadOrder($root) {        $queue = new Queue();        if ($root != null) {            $queue->enqueue($root);        }        while (!$queue->isEmpty()) {            $pointer = $queue->dequeue();            $this->visit_func($pointer);            if ($pointer->left != null) {                $queue->enqueue($pointer->left);            }            if ($pointer->right != null) {                $queue->enqueue($pointer->right);            }        }    }    /**     * 前序遍历(递归)     * @param $root     */    public function preOrderR($root) {        if ($root != null) {            $this->visit_func($root);            $this->preOrderR($root->left);            $this->preOrderR($root->right);        }    }    /**     * 前序遍历(非递归)     * @param $root     */    public function preOrderNR($root) {        $stack = new Stack();        $pointer = $root;        while ($pointer != null || !$stack.isEmpty()) {            if ($pointer != null) {                $this->visit_func($pointer);                if ($pointer->right != null) {                    $stack->push($pointer->right);                }                $pointer = $pointer->left;            }            else {                $pointer = $stack->pop();            }        }    }    /**     * 中序遍历(递归)     * @param $root     */    public function inOrderR($root) {        if ($root != null) {            $this->preOrderR($root->left);            $this->visit_func($root);            $this->preOrderR($root->right);        }    }    /**     * 中序遍历(非递归)     * @param $root     */    public function inOrderNR($root) {        $stack = new Stack();        $pointer = $root;        while ($pointer != null || !$stack.isEmpty()) {            if ($pointer != null) {                $stack->push($pointer);                $pointer = $pointer->left;            }            else {                $pointer = $stack->pop();                $this->visit_func($pointer);                $pointer = $pointer->right;            }        }    }}

(8)二叉搜索树的插入

 

Class BinarySearchTree {    /**     * 二叉搜索树插入     * @param $root 此处认为root不空     * @param $val     */    public function insert($root, $val) {        $pointer = $root;        $prev = null;        while ($pointer != null) {            $prev = $pointer;            if ($val == $pointer->val) {                return false;            }            else if ($val < $pointer->val) {                $pointer = $pointer->left;            }            else {                $pointer = $pointer->right;            }        }        $node = new BinarySearchNode($val);        if ($val < $prev->val) {            $prev->left = $node;        } else {            $prev->right = $node;        }        return true;    }}

 

转载于:https://www.cnblogs.com/livepeace/p/8227806.html

你可能感兴趣的文章
Vue v-for渲染页面,获取不到DOM元素解析
查看>>
一个典型案例为你解读TDSQL 全时态数据库系统
查看>>
视频云资深技术专家李彬:传统企业如何进行多媒体数字化转型?
查看>>
1. Two Sum (Easy)
查看>>
【linux】与 用户、权限 有关的常用命令
查看>>
对Javascript 类、原型链、继承的理解
查看>>
Go 的 fake-useragent 了解一下
查看>>
创建topic——kafka源码探究之一
查看>>
【Laravel】Laravel 框架关键技术解析·读书笔记(一)
查看>>
ES6入门---let和const
查看>>
Codepen 每日精选(2018-4-10)
查看>>
git学习笔记
查看>>
Thinking——Debian On Windows初试
查看>>
看完你也想编写自己的 react 插件
查看>>
数据结构与算法:常见排序算法
查看>>
记录一次并发读取MongoDB的踩坑过程
查看>>
初识JavaScript EventLoop
查看>>
MVC是什么
查看>>
关于 emotion 初步使用的笔记
查看>>
PHP 怎样在同一个域名下两个不同的项目做独立的登录机制?
查看>>