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

来源:互联网 发布:考勤表制作软件 编辑:程序博客网 时间:2024/05/27 14:12

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">逆波兰表示法,俗称后缀表示法。</span>

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

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

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

下面是PHP代码:

<?php/** * Created by PhpStorm. * User: lzf * Date: 15/6/28 * Time: 21:40 */error_reporting(0);$expr = '1+(5-6*7)*9';$expr = '2+45+6/2-45+(23-4)*5';$expr = '2+45+6/2-20';//运算符栈,在栈里插入最小优先级的运算符,避免进入不到去运算符比较的循环里$opArr = array('#');//运算数栈;$oprandArr = array();//运算符优先级$opLevelArr = array(    ')' => 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;

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


0 0