PHP计算表达式-栈

本文详细阐述了使用PHP解析并计算表达式的过程,包括如何识别数字与运算符,实现优先级运算,以及最终得到计算结果的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<?php 
/**
 * 计算表达式思路
 * 1+2*3-2
 * 思路:
 * 1、扫描每个字符
 * 2、判断是否运算符和数字
 * 3、数字直接进栈
 * 4、运算符
 *     1、第一个运算符直接入栈
 *     2、N个运算符要与之前运算符比较
 *         1、如果当前运算符大于栈顶的运算符
 *             1、从数栈取出两个数字进行运算,其实这个就是优先级运算
 *             2、把结果入栈
 *         2、如果不大于直接入栈
 *  5、得到平级运算表达式
 *  6、遍历运算符出栈进行运算,然后在入栈,一直到运算符为空。
 * @author wangdk
 *
 */
class Expression
{
    public $numArray = array();
    public $operArray = array();
    
    /**
     * 判断是否为数字
     */
    public function isNumeric($str) {
        return is_numeric($str);
    }
    
    /**
     * 判断是否为运算符
     */
    public function isOperation($str) {
        if ($str == '+' || $str == '-') {
            return 1;
        }
        
        if ($str == '*' || $str == '/') {
            return 2;
        }
        return 0;
    }
    
    /**
     * 根据运算符进行运算
     */
    public function calc($ch, $numA, $numB) {
        $result = 0;
        
        switch($ch) {
            case '+':
                $result = $numA + $numB;
                break;
            case '-':
                $result = $numB - $numA;
                break;
            case '*':
                $result = $numA * $numB;
                break;
            case '/':
                $result = $numB / $numA;
                break;
        }
        
        return $result;
    }
    
    /**
     * 扫描表达式进行入栈
     */
    public function getResult($str) {
        $count = strlen($str);
        for ($i = 0; $i < $count; $i++) {
            // 数字直接入栈
            if ($this->isNumeric($str[$i])) {
                array_push($this->numArray, $str[$i]);
            } else {
                // 第一个运算符直接入栈
                if (empty($this->operArray)) {
                    $this->operArray[] = $str[$i];
                } else {
                    // 多个运算符开始比较,去掉优先级
                    $operArrayCopy = $this->operArray;
                    $prev_operation = array_pop($operArrayCopy);
                    // 如果当前运算符号小于  上一个运算符
                    if ($this->isOperation($str[$i]) <= $this->isOperation($prev_operation)) {
                        // 运算
                        $prev_operation = array_pop($this->operArray);
                        $first_num = array_pop($this->numArray);
                        $second_num = array_pop($this->numArray);
                        
                        $result = $this->calc($prev_operation, $first_num, $second_num);
                        
                        $this->numArray[] = $result;
                        array_push($this->operArray, $str[$i]);
                    } else {
                        array_push($this->operArray, $str[$i]);
                    }
                }
            }
        }
        // 遍历平级运算符,进行运算
        $operArrayCount = count($this->operArray);
        while($operArrayCount) {
            
            $prev_operation = array_pop($this->operArray);
            $first_num = array_pop($this->numArray);
            $second_num = array_pop($this->numArray);
            
            $result = $this->calc($prev_operation, $first_num, $second_num);
            $this->numArray[] = $result;
            
            $operArrayCount = count($this->operArray);
        }
        
    }
    
    
}

$e = new Expression();
$e->getResult('1+2*3+4*8');
echo '<pre>';
print_r($e->numArray);
print_r($e->operArray)
?>

转载于:https://my.oschina.net/wangdk/blog/158787

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值