php逆波兰表达式,我就给一个PHP逆波兰表达式的算法吧---工资计算专用

这篇博客介绍了如何使用PHP实现一个逆波兰表达式算法来计算自定义的工资公式。作者提供了一个类,该类可以接受变量值和计算公式,通过将表达式分解成符号数组,转换为逆波兰表示法,最后计算得出结果。示例中展示了如何处理包含变量和常数的表达式,并给出了关键函数的实现,包括字符串转数组、数组转逆波兰表达式和从逆波兰表达式计算值的步骤。
摘要由CSDN通过智能技术生成

有个网友写信给我谈到关于PHP计算工资问题。我以前一篇文章中谈到过一种计算工资的方法,不过是偷巧,利用现有的表达式的工具,现在既然有人想要,我就给出一个逆波兰的算法。 我们的目标是实现如下的计算公式: 假设有一个计算公式如下: $expression = "(F1*F12+10.34)"; 其中的变量值如下: $expression_value = Array('F1'=>10, 'F12'=>20); 我们希望用PHP构建一个类来计算出这个表达式的值。这种应用主要用于web工资管理中,用户可以自定义其工资相公式的情况 $rpn = new Math_Rpn(); $rpn->setExpressionValue($expression_value); echo $rpn->calculate($expression,'deg',false); // 即为相应的值 解析逆波兰表达式的方法,编译原理中有,就是先把表达式分解成符号数组,然后求逆波兰式,最后根据逆波兰式得到其结果。 我分别把三个函数贴在下面,其实本质我就是对Pear的RPN函数进行了Hack. function _stringToArray () { $temp_operator = null; $temp_value = null; $this->_input = str_replace(" ","",$this->_input); for($i = 0; $i < strlen($this->_input); $i++) { if ($this->_input[$i] == ' ') { if ($temp_operator != null) { array_push($this->_input_array, $temp_operator); $temp_operator = null; } if ($temp_value != null) { array_push($this->_input_array, $temp_value); $temp_value = null; } } elseif (($temp_value == null) && $temp_operator != ')' && (!array_key_exists($temp_operator,$this->_operation) || !array_key_exists(2,$this->_operation[$temp_operator]) || $this->_operation[$temp_operator][2]>0) && ($this->_input[$i] == '-')) { if ($temp_operator != null) { array_push($this->_input_array, $temp_operator); $temp_operator = null; } array_push($this->_input_array, '-1'); array_push($this->_input_array, '*'); //} elseif ((is_numeric($this->_input[$i])) || ($this->_input[$i] == '.')) { } elseif ((is_numeric($this->_input[$i])) || ($this->_input[$i] == '.') || ($this->_input[$i] == 'F')) { if ($temp_operator != null) { array_push($this->_input_array, $temp_operator); $temp_operator = null; } $temp_value .= $this->_input[$i]; } else { if ($this->_keyExists($temp_operator, $this->_operation, 1)) { array_push($this->_input_array, $temp_operator); $temp_operator = null; } if ($temp_value != null) { array_push($this->_input_array, $temp_value); $temp_value = null; } $temp_operator .= $this->_input[$i]; } } if ($temp_operator != null && $temp_operator != ' ') { array_push($this->_input_array, $temp_operator); } elseif($temp_value != null && $temp_value != ' ') { array_push($this->_input_array, $temp_value); } // $this->_testInput(); print_r($this->_expression_value); print_r($this->_input_array); return $this->_input_array; } function _arrayToRpn() { if ($this->_error <> null) { $this->_output = array(); return $this->_output; } for($i = 0; $i < count($this->_input_array); $i++) { $temp = $this->_input_array[$i]; if (is_numeric($temp)) { $this->_outputAdd($temp); } else if($this->_keyExists($temp, $this->_expression_value, 0)) { $this->_outputAdd($this->_expression_value[$temp]); } else { if ($temp == ')') { while(!$this->_stackEmpty() && ($this->_stackPriority() >= 1)) { $this->_outputAdd($this->_stackDelete()); } if (!$this->_stackEmpty()) { $this->_stackDelete(); } } elseif ($temp=='(') { $this->_stackAdd($temp); } elseif (($this->_stackEmpty()) || (($this->_priority($temp) > $this->_stackPriority()))) { $this-> _stackAdd($temp); } else { while(!$this->_stackEmpty() && ($this->_priority($temp) <= $this->_stackPriority())) { $this->_outputAdd($this->_stackDelete()); } $this->_stackAdd($temp); } } } while(!$this->_stackEmpty()) { $this->_outputAdd($this->_stackDelete()); } return $this->_output; } function _rpnToValue() { $time1 = $this->_getMicroTime(); if ($this->_error <> null) { $this->_value = null; return $this->_value; } $this->_value = 0; $temp = $this->_output; do { $pos = $this->_nextOperator($temp); if ($pos == -1) { $this->_error = $this->_raiseError('Syntax error'); $this->_value = null; return $this->_value; } $operator = $this->_operation[$temp[$pos]]; $arg = $operator[2]; $function = $operator[3]; if (($arg==2) && (!isset($temp[$pos-1]) || !is_numeric($temp[$pos-1]) || !isset($temp[$pos-2]) || !is_numeric($temp[$pos-2]))) { $this->_error = $this->_raiseError('Syntax error'); $this->_value = null; return $this->_value; } elseif (($arg==1) && (!isset($temp[$pos-1]) || !is_numeric($temp[$pos-1]))) { $this->_error = $this->_raiseError('Syntax error'); $this->_value = null; return $this->_value; } if(is_array($function)) { if($arg==2) $arg_array = array($temp[$pos-2],$temp[$pos-1]); elseif($arg==1) $arg_array = array($temp[$pos-1]); else $arg_array = array(); if($function['type'] == 'userFunction') { $this->_value = call_user_func_array($function['function'], $arg_array); } else { $function_array = array(&$function['class'], $function['method']); $this->_value = call_user_func_array($function_array, $arg_array); } } else { $this->_value = $this->$function($temp, $pos); } if ($this->_isNan($this->_value)) { $this->_error = $this->_raiseError('NAN value'); $this->_value = null; return $this->_value; } elseif ($this->_isInfinite($this->_value)) { $this->_error = $this->_raiseError('Infinite value'); $this->_value = null; return $this->_value; } elseif (is_null($this->_value)) { return $this->_value; } $temp = $this->_refresh($temp, $pos, $arg, $this->_value); } while(count($temp) > 1); $this->_value = $temp[0]; $time2 = $this->_getMicroTime(); $this->_timer = $time2 - $time1; return $this->_value; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值