逆波兰表达式的 PHP 实现

1. 简介
逆波兰式(Reverse Polish notation,RPN,或逆波兰记法),也叫后缀表达式(将运算符写在操作数之后)
2. 例子

我们平时写a+b,这是中缀表达式,写成后缀表达式就是:ab+
下列例子,左侧为中缀,右侧为后缀即逆波兰式

  1. (1 + 3) / 4 => 1,3,+,4,/
  2. ((2 * 3) + 4) * 5 => 2,3,*,4,+,5,*
4. PHP 实现
  1. 逆波兰式可以很简单的通过 入栈出栈 两种操作即可完成包含 加减乘除 的普通表达式运算,具体为 stack1stack2 两个栈,逆波兰式放入 s1,然后逐一取出其中元素,如果是数字则入 s2,如果运算符,则从 s2 取出两个进行运算,将结果入 s2,重复上述操作到整个完成即可,用 array_shiftarray_unshift 模拟 入栈出栈 动作,代码如下:
function evalRPN2($tokens) {
    $data=[];
    $type=['+','-','*','/'];
    for($i=0;$i<count($tokens);$i++) {
        if(!in_array($tokens[$i],$type)) {
            array_unshift($data,intval($tokens[$i]));
        }else{
            $val1=array_shift($data);
            $val2=array_shift($data);
            switch($tokens[$i]) {
                case '+':
                    array_unshift($data,$val2+$val1);
                    break;
                case '-':
                    array_unshift($data,$val2-$val1);
                    break;
                case '*':
                    array_unshift($data,$val2*$val1);
                    break;
                case '/':
                    array_unshift($data,intval($val2/$val1));
                    break;
                default:

            }
        }
    }
    return current($data);
}
  1. 另外是通过递归,首先取出最后一位的操作符,然后取出前一位元素,数字则存为待运算的数字,操作符则将剩余逆波兰式进行递归,直到取出其中所有元素为止,代码如下:
function evalRPN(&$tokens) {
    if (sizeof($tokens) > 1) {
        $operator = array_pop($tokens);
        $second = end($tokens);
        if (in_array($second, ['+', '-', '/', '*'])) {
            $value = evalRPN($tokens);
            $second = $value;
        } else {
            $second = array_pop($tokens);
        }
        $first = end($tokens);
        if (in_array($first, ['+', '-', '/', '*'])) {
            $value = evalRPN($tokens);
            $first = $value;
        } else {
            $first = array_pop($tokens);
        }
        switch ($operator) {
            case '+':
                $value = $first + $second;
                break;
            case '-':
                $value = $first - $second;
                break;
            case '/':
                $value = intval($first / $second);
                break;
            case '*':
                $value = $first * $second;
        }
    } else {
        $value = array_pop($tokens);
    }
    return $value;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值