最近在整理资料时发现了一些以前收藏的有趣代码
计划逐步将他们移植到 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
计划逐步将他们移植到 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
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');