php使用逆波兰算法实现四则运算器

逆波兰表示法,俗称后缀表示法。

曾经被别人问过,四则运算器的实现,当时仅仅是算的两个数的,周日研究了下四则运算表达式,看到逆波兰算法,从看算法思路到实现并验证花了近2个多小时,怕以后忘掉,所以记录下来,放到工具包中。

逆波兰算法思路,重点是理解大括号的压栈和出栈,这里就不细说了。

有个博客写的不错,入口:http://blog.sina.com.cn/s/blog_3c6889fe0100sb84.html

下面是PHP代码:

 2,
    '(' => 3,
    '+' => 4,
    '-' => 4,
    '*' => 5,
    '/' => 5,
    '#' => 1
);

$bolanExprArr = array();

$exprLen = strlen($expr);
$inop = false;
$opNums = "";

//解析表达式
for($i = 0;$i <= $exprLen;$i++){
    $char = $expr[$i];
    //获取当前字符的优先级
    $level = intval($opLevelArr[$char]);
    //如果大于0,表示是运算符,否则是运算数,直接输出
    if($level > 0){
          $inop = true;
          //如果碰到左大括号,直接入栈
          if($level == 3){
              array_push($opArr,$char);continue;
          }

          //与栈顶运算符比较,如果当前运算符优先级小于栈顶运算符,则栈顶运算符弹出,一直到当前运算符优先级不小于栈顶
          while($op = array_pop($opArr)){
              if($op){
                  $currentLevel = intval($opLevelArr[$op]);
                  if($currentLevel == 3 && $level == 2) {
                      break;
                  }elseif($currentLevel >= $level && $currentLevel != 3){
                      array_push($bolanExprArr,$op);
                  }else{
                      array_push($opArr,$op);
                      array_push($opArr,$char);
                      break;
                  }
              }
          }
    }else{
        //多位数拼接成一位数
        $opNums .= $char;
        if($opLevelArr[$expr[$i+1]] > 0){
            array_push($bolanExprArr, $opNums);
            $opNums = "";
        }
    }
}
array_push($bolanExprArr, $opNums);

//输出剩余运算符
while($leftOp = array_pop($opArr)){
    if($leftOp != '#'){
        array_push($bolanExprArr,$leftOp);
    }
}

//计算逆波兰表达式。
foreach($bolanExprArr as $v){
    if(!isset($opLevelArr[$v])){
        array_push($oprandArr,$v);
    }else{
        $op1 = array_pop($oprandArr);
        $op2 = array_pop($oprandArr);

        eval("\$result = $op2 $v $op1;");

        array_push($oprandArr,$result);
    }
}

echo $result;

如有什么错误,请大家批评指证。


你可能感兴趣的:(php)