最近在整理资料时发现了一些以前收藏的有趣代码
计划逐步将他们移植到 PHP 供有兴趣的人参考
/**
 * 逆波兰表达式计算
 * 中缀转后缀
 **/
function postfix($infix) {
$priority = array( //算符优先级
'+' => 1, '-' => 1,
'*' => 2, '/' => 2,
'(' => 0, ')' => 0,
'.' => 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
);
$stack = array(); //符号栈
$data = array(); //数值栈 
$i = $top = 0;
$last = -1;
$len = strlen($infix);
while($i<$len) {
switch($infix{$i}) {
case '(':
array_unshift($stack, $infix{$i});
break;
case '+': case '-': case '*': case '/':
if($t != '') array_unshift($data, $t);
$t = '';
while($priority[$stack[0]] >= $priority[$infix{$i}]) {
postfix_callback(array_shift($stack), $data);
}
array_unshift($stack, $infix{$i});
break;
case ')':
if($t != '') array_unshift($data, $t);
$t = '';
while($stack[0] != '(') {
postfix_callback(array_shift($stack), $data);
}
array_shift($stack);
break;
default:
if($i > $last+1 && $t != '') {
array_unshift($data, $t);
$t = '';
}
$t .= $infix{$i};
$last = $i;
break; 
}
$i++;
}
while($stack) {
postfix_callback(array_shift($stack), $data);
}
return $data[0];
}/**
 * postfix 的工作函数
 * 用于计算表达式的值
 **/
function postfix_callback($ch, &$data) {
$b = array_shift($data);
switch($ch) {
case '+':
$data[0] += $b;
break;
case '-':
$data[0] -= $b;
break;
case '*':
$data[0] *= $b;
break;
case '/':
$data[0] /= $b;
break;
}
}
测试例echo postfix( '(2+3)*(3+4)' ); //out 35

解决方案 »

  1.   

    非逆波兰,递归解四则,,,蛮早以前写的,,放在角落,好不容易搜出来……添砖加瓦傻代码,刚才看了一下,没有任何容错机制,思路很简单,脱括号、去乘除、剩下的就是加减了class cls_calculate{
    public function __construct(){}
    public function calculate($str){
    do{
    $str = preg_replace_callback('#\(([^\(\)]*)\)#', array(&$this, '_doff_add_sub'), $tmp = $str);
    }while($tmp != $str);
    return $this->_doff_add_sub($str);
    }
    private function _doff_add_sub($str){
    $str = is_array($str) ? $str[1] : $str;
    do{
    $str = str_replace(array('++', '+-', '--', '-+', ' '), array('+', '-', '+', '-', ''), $tmp = $str);
    $str = preg_replace_callback('#([\d]+(\.[\d]+)?)([*|/])(-?[\d]+(\.[\d]+)?)#', array(&$this, '_doff_mul_div'), $str, 1);
    }while($tmp != $str);
    $items = preg_split('#[+-]#', $str, -1, PREG_SPLIT_OFFSET_CAPTURE);
    $result = $items[0][0];
    for($i=1,$n=count($items);$i<$n;++$i){
    $str{$items[$i][1]-1} == '+' ? $result += $items[$i][0] : $result -= $items[$i][0];
    }
    return $result;
    }
    private function _doff_mul_div($str){
    return $str[3] == '*' ? $str[1]*$str[4] : $str[1]/$str[4];
    }
    }
    $calculate = new cls_calculate;
    echo $calculate->calculate('-1*-2/((6-12)/(4-2/2))*(-3+2/1-1)');
    echo "\n";
    echo $calculate->calculate('-1*2');
      

  2.   

    对了,,不需要 &,$this即可
      

  3.   

    想起了以前的事情……记得以前面试ubisoft的时候,出过一道题目,写一个编辑器包括普通运算、大中小括号等,然后给了一个各种括号套括号、括号包含括号的式子作为输入,要求程序自我判断所给式子是否是运算式(好像就是是否少括号、加号乘号不能挨着这类判断),反正当时答得很乱,我还有到了编译原理的知识又是画图又是算……