逆波兰表达式计算

xuzuning 2011-12-16 09:31:22
最近在整理资料时发现了一些以前收藏的有趣代码
计划逐步将他们移植到 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
...全文
302 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
夏之冰雪 2011-12-24
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 amani11 的回复:]

非逆波兰,递归解四则,,,

蛮早以前写的,,放在角落,好不容易搜出来……添砖加瓦

傻代码,刚才看了一下,没有任何容错机制,思路很简单,脱括号、去乘除、剩下的就是加减了
PHP code

class cls_calculate{
public function __construct(){}
public function calculate($str){
……
[/Quote]
想起了以前的事情……记得以前面试ubisoft的时候,出过一道题目,写一个编辑器包括普通运算、大中小括号等,然后给了一个各种括号套括号、括号包含括号的式子作为输入,要求程序自我判断所给式子是否是运算式(好像就是是否少括号、加号乘号不能挨着这类判断),反正当时答得很乱,我还有到了编译原理的知识又是画图又是算……
amani11 2011-12-24
  • 打赏
  • 举报
回复
对了,,不需要 &,$this即可
amani11 2011-12-24
  • 打赏
  • 举报
回复
非逆波兰,递归解四则,,,

蛮早以前写的,,放在角落,好不容易搜出来……添砖加瓦

傻代码,刚才看了一下,没有任何容错机制,思路很简单,脱括号、去乘除、剩下的就是加减了

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');
ci1699 2011-12-17
  • 打赏
  • 举报
回复
这个好玩哈
  • 打赏
  • 举报
回复
eval('1+1');
凡人01 2011-12-17
  • 打赏
  • 举报
回复
前排占座, 板主老大给力.
ZT_King 2011-12-16
  • 打赏
  • 举报
回复
前排占座, 板主老大给力.
ohmygirl 2011-12-16
  • 打赏
  • 举报
回复
这个好东西。
xiachao2008 2011-12-16
  • 打赏
  • 举报
回复
先回贴在看

20,360

社区成员

发帖
与我相关
我的任务
社区描述
“超文本预处理器”,是在服务器端执行的脚本语言,尤其适用于Web开发并可嵌入HTML中。PHP语法利用了C、Java和Perl,该语言的主要目标是允许web开发人员快速编写动态网页。
phpphpstorm 技术论坛(原bbs)
社区管理员
  • 开源资源社区
  • phpstory
  • xuzuning
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧