四则运算表达式,我们书面使用的叫做中缀表达式,而计算器,却更加喜欢后缀表达,括号优先级,加减乘除优先级等使得运算中缀四则表达式变得困难。这个时候引入了一种计算机喜欢的格式,叫做后缀表达式。本文以PHP代码,实现中缀表达式转后缀表达式的逻辑。

    本文以PHP为代码环境,有人会说高级语言直接写表达式就好了,它们会算,可是他们为什么会算,怎么算的,还是需要把中缀表达式转为后缀表达式。因此本文代码只是模拟一个逻辑。

    比如:传统的四则运算表达式(中缀表达式)是9 + ( 3 - 1 ) * 3 + 10 / 2,对应的后缀表达式就是9 3 1 - 3 * + 10 2 / +。

    转换逻辑:一个字符一个字符的输入,如果是数字则直接输出;如果是左括号则直接入栈;如果是右括号则开始出栈,直到遇到第一次左括号为止;如果是加减乘除,则判断,如果栈顶也是符号,且输入的符号的优先级不高于栈顶的符号优先级,则全部出栈,否则该输入的符号入栈。

<?php

/**

 * 将输入的字符按照中缀表达式转后缀表达式的规则处理

 * @param $str 输入的字符

 * @param $stack 栈

 * @param $newStrList 新的表达式

 */

function suffix($str, &$stack, &$newStrList){

    //如果是数字则输出

    if(is_numeric($str)){

        $newStrList .= $str . ' ';

    }

    //如果是左括号则入栈

    else if($str == '('){

        $stack[] = $str;

    }

    //如果是右括号则将最近的左括号之前的所有数据出栈

    else if($str == ')'){

        while($arrPop = array_pop($stack)){

            if($arrPop == '('){

                break;

            }

            $newStrList .= $arrPop . ' ';

        }

    }

    //如果是加减乘除则判断与栈顶符号优先级

    else if(in_array($str, array('+', '-', '*', '/')) && count($stack) > 0){

        $key  = (count($stack) - 1);

        if(in_array($stack[$key], array('+', '-', '*', '/'))){

            //该符号优先级不高于栈顶符号的

            if(checkPriority($str, $stack[$key]) != 1){

                for($i=$key; $i>=0; $i--){

                    if($stack[$i] == '('){

                        break;

                    }

                    $newStrList .= $stack[$i] . ' ';

                    unset($stack[$i]);

                    $stack = array_values($stack);

                }

            }

        }

        //本次的符号入栈

        $stack[] = $str;

    }else{

        $stack[] = $str;

    }

}


/**

 * 判断运算符的优先级

 * @param $operatorA

 * @param $operatorB

 * @return A大于B返回1,A等于B返回0,A小于B返回-1

 */

function checkPriority($operatorA, $operatorB){

    switch($operatorA){

        case '+':

        case '-':

            if($operatorB == '+' || $operatorB == '-'){

                return 0;

            }else if($operatorB == '*' || $operatorB == '/'){

                return -1;

            }

            break;

        case '*':

        case '/':

            if($operatorB == '+' || $operatorB == '-'){

                return 1;

            }else if($operatorB == '*' || $operatorB == '/'){

                return 0;

            }

            break;

        default:

            exit('error');

    }

}

//栈

$stack = array();

//待转换的表达式

$strList = '9 + ( 3 - 1 ) * 3 + 10 / 2';

//新的表达式

$newStrList = '';

$strList = explode(' ', $strList);

foreach($strList as $str){

    if($str != ' '){

        suffix($str, $stack, $newStrList);

    }

}

//数组反转

while($s = array_pop($stack)){

    $newStrList .= $s . ' ';

}

echo $newStrList;


标签: PHP, 后缀, 中缀

添加新评论