计算器 | 逆波兰表达式
来源:互联网 发布:淘宝怎么出售游戏账号 编辑:程序博客网 时间:2024/04/28 07:57
1.实现原理:
说明:在我原来做的逆波兰计算器中,postfix是用来表示逆波兰表达式的。但是和buptpatriot讨论后,想直接实现,下面是直接实现的方法:
首先,定义优先级:
function level($op) {switch ($op) {case '+':case '-':return 1;case '*':case '/':return 2;case '^': return 3;}}
之后,扫描输入序列,读取输入的字符串,把其中的数字(可能是浮点型,负数)和操作符提取出来
收集浮点数:
function readin($expr) {$expr = str_split($expr);$len = count($expr);$infix = array();$opts = array('+','-','*','/','(',')');$num = "";for($i = 0; $i < $len; $i++) {if(in_array($expr[$i], $opts) || ($i == $len-1)) {if($num = floatval($num)) {array_push($infix, $num);$num = "";}if($expr[$i] == '-' && ($expr[$i-1] == NULL || $expr[$i-1] == '(') && (is_numeric($expr[$i+1]) || $expr[$i+1] == '(')) {$expr[$i] = '^'; //unary negotion}array_push($infix, $expr[$i]);}else {$num .= $expr[$i];}}var_dump($infix);return $infix;}
对于否定符号(-)做处理:
if($expr[$i] == '-' && ($expr[$i-1] == NULL || $expr[$i-1] == '(') && (is_numeric($expr[$i+1]) || $expr[$i+1] == '(')) {$expr[$i] = '^'; }
此时,否定符号'-'转化成'^'
1) 如果是数字,则存入栈 postfix 中;
2) 如果是运算符:
2.1)是 ‘(’ ,则存入栈 stack 中;
2.2)是‘+’,‘-’,‘*’,‘/’,‘’,则检查栈stack是否为空:
2.2.1)stack 为空:则存入栈内
2.2.2 ) stack不为空,执行下面的操作:
从stack中弹出一个元素op
如果这个元素的不是 ‘(’ 且弹出元素的优先级大于当前扫描元素的优先级,就将弹出元素存入postfix栈内,同时从postfix中弹出2个元素a,b,计算a op b的结 果,将其存入postfix中;
否则,把弹出元素op重新压入栈stack内
最后,当前扫描到的运算符入栈stack
2.3) 是‘^’ :执行下面的操作:
从postfix中弹出1个元素a,将(0-a)存入postfix中;
2.4) 是‘)’ :执行下面的操作:
弹出元素存入postfix栈内,同时从postfix中弹出2个元素a,b,计 算a op b的结果,将其存入postfix中;
直到弹出元素为'(';
画一个表来看:4/((3-1)*2) = 1的计算过程
currentstackpostfix4empty4//4(/(4(/((43/((43-/((-431/((-431)/(42*/(*422/(*422)/44 empty1(result)2.php 代码:
<html><head><title>Reverse Polish Notation Calculator</title></head><body><h1>Calculator</h1><h3>by wusuopubupt</h3><form id="my_form" method="POST" action="<?php echo $_SERVER['SCRIPT_NAME'];?>"><input type="text" name="expr" placeholder="input expression to calculate!"/></form><?phpif(isset($_POST['expr'])) {$expr = readin($_POST['expr']);$result = cal($expr);echo "result is:";var_dump($result);}function readin($expr) {$expr = str_split($expr);$len = count($expr);$infix = array();$opts = array('+','-','*','/','(',')');$num = "";for($i = 0; $i < $len; $i++) {if(in_array($expr[$i], $opts) || ($i == $len-1)) {if($num = floatval($num)) {array_push($infix, $num);$num = "";}if($expr[$i] == '-' && ($expr[$i-1] == NULL || $expr[$i-1] == '(') && (is_numeric($expr[$i+1]) || $expr[$i+1] == '(')) {$expr[$i] = '^'; }array_push($infix, $expr[$i]);}else {$num .= $expr[$i];}}var_dump($infix);return $infix;}function cal($expr) {$postfix_expr = infix2postfix($expr);var_dump($postfix_expr);$len = count($postfix_expr);$stack = array();$result = 0;for($i = 0; $i < $len; $i++) {$var = $postfix_expr[$i];if(is_numeric($var)) {array_push($stack, $var);}else {if($var != '^') {$rhs = array_pop($stack); //right hand side$lhs = array_pop($stack); //left hand sidearray_push($stack,operate($lhs,$var,$rhs));}else { $rhs = 0 - array_pop($stack);array_push($stack, $rhs);} }}return array_pop($stack);}function infix2postfix($expr) {$len = count($expr);$stack = array();$postfix = array();for($i = 0; $i < $len; $i++) {if(is_numeric($expr[$i])) {$postfix[] = $expr[$i];}else {if($expr[$i] == '(') {array_push($stack, $expr[$i]);}if($expr[$i] == '+' || $expr[$i] == '-' || $expr[$i] == '*' || $expr[$i] == '/' || $expr[$i] == '^') {if(!empty($stack)){$op = array_pop($stack);if($op != '(' && (level($op) >= level($expr[$i]))) {array_push($postfix,$op);}else {array_push($stack, $op);}}array_push($stack, $expr[$i]);}if($expr[$i] == ')') {while(($op = array_pop($stack)) != '(') {array_push($postfix,$op);}}}}while(($last_op = array_pop($stack)) != NULL){array_push($postfix, $last_op);}return $postfix;}function operate($left,$op,$right) {switch($op) {case '+':return $left + $right;case '-':return $left - $right;case '*':return $left * $right;case '/':return $left / $right;}}function level($op) {switch ($op) {case '+':case '-':return 1;case '*':case '/':return 2;case '^': return 3;}}?></body></html>
3.运行结果:
输入:4/((3-1)*2)
输出:
包含 否定符号的结果:
输入:-(-1.2+1.8)/(1/3.0)
输出:
- 计算器 | 逆波兰表达式
- 逆波兰表达式计算器
- 逆波兰表达式思想下的计算器
- 实现逆波兰表达式的java计算器
- 基于逆波兰表达式的计算器
- 计算器(逆波兰运算表达式)
- HDU 1237 简单计算器 逆波兰表达式
- 用逆波兰表达式的三角函数计算器
- java 逆波兰表达式 (后缀表达式) 计算器
- 波兰、逆波兰表达式
- 逆波兰式实现四则运算表达式计算器支持括号、十六进制
- MFC计算器 用vector实现和计算逆波兰表达式
- 栈_逆波兰表达式_计算器实现_Golang版本
- 使用逆波兰式(后缀表达式)实现多功能计算器
- 逆波兰表达式实现计算器(附c++代码)
- C++逆波兰表达式转化实现简单计算器
- 逆波兰计算器
- 逆波兰实现计算器
- 菜鸟的学习之路(4) —java static和final使用
- JS的无缝滚动
- HDU-4727 水题一个
- migrate gentoo from virtualbox to vmware vsphere
- 24点算法 | 逆波兰表达式实现去重复
- 计算器 | 逆波兰表达式
- 多进程和多线程的优缺点
- 2014网银在线校园招聘笔试
- ATS
- 学习笔记----C++ 中iomanip头文件的使用
- CCCallFunc CCCallFuncO CCCallFuncN CCCallFuncND 的区别
- vimgdb安装与使用
- vsftpd 服务器配置:虚拟用户
- KMP小结