Home  >  Article  >  Backend Development  >  Algorithm of PHP reverse Polish expression - special for salary calculation_PHP tutorial

Algorithm of PHP reverse Polish expression - special for salary calculation_PHP tutorial

WBOY
WBOYOriginal
2016-07-15 13:23:48936browse

A netizen wrote to me about the issue of salary calculation in PHP. I talked about a method of calculating wages in a previous article, but it was just a clever way to use existing expression tools. Now since someone wants it, I will give you a reverse Polish algorithm.

Our goal is to achieve the following calculation formula:

Suppose there is a calculation formula as follows:

<p>$expression = "(F1*F12+10.34)";</p>

The variable values ​​are as follows:

<p>$expression_value = Array('F1'=>10,'F12'=>20);</p>

We want to build a class in PHP to calculate the value of this expression. This application is mainly used in web salary management, where users can customize their salary formulas.

<p>$rpn = new Math_Rpn();<br>$rpn->setExpressionValue($expression_value);  <br>echo $rpn->calculate($expression,'deg',false); // 即为相应的值</p>

The method of parsing the reverse Polish expression, which is included in the compilation principle, is to first decompose the expression into a symbolic array, then find the reverse Polish expression, and finally obtain it according to the reverse Polish expression as a result.

I posted the three functions below. In fact, I basically hacked Pear's RPN function.

<p>function _stringToArray () {<br>$temp_operator = null;<br>$temp_value = null;</p><p>$this->_input = str_replace(" ","",$this->_input);</p><p>for($i = 0; $i _input); $i++) {<br>if ($this->_input[$i] == ' ') {<br>  if ($temp_operator != null) {<br>array_push($this->_input_array, $temp_operator);<br>$temp_operator = null;<br>  }<br>  if ($temp_value != null) {<br>array_push($this->_input_array, $temp_value);<br>$temp_value = null;<br>  }<br>} elseif (($temp_value == null) && $temp_operator != ')' && </p><p>(!array_key_exists($temp_operator,$this->_operation) || </p><p>!array_key_exists(2,$this->_operation[$temp_operator]) || </p><p>$this->_operation[$temp_operator][2]>0) && ($this->_input[$i] == '-')) {<br>  if ($temp_operator != null) {<br>array_push($this->_input_array, $temp_operator);<br>$temp_operator = null;<br>  }</p><p>  array_push($this->_input_array, '-1');<br>  array_push($this->_input_array, '*');<br>//} elseif ((is_numeric($this->_input[$i])) || ($this->_input[$i] == '.')) {<br>} elseif ((is_numeric($this->_input[$i])) || ($this->_input[$i] == '.') || </p><p>($this->_input[$i] == 'F')) {<br>  if ($temp_operator != null) {<br>array_push($this->_input_array, $temp_operator);<br>$temp_operator = null;<br>  }</p><p>  $temp_value .= $this->_input[$i];<br>} else {<br>  if ($this->_keyExists($temp_operator, $this->_operation, 1)) {<br>array_push($this->_input_array, $temp_operator);<br>$temp_operator = null;<br>  }</p><p>  if ($temp_value != null) {<br>array_push($this->_input_array, $temp_value);<br>$temp_value = null;<br>  }</p><p>  $temp_operator .= $this->_input[$i];<br>}<br>}</p><p>if ($temp_operator != null && $temp_operator != ' ') {<br>array_push($this->_input_array, $temp_operator);<br>} elseif($temp_value != null && $temp_value != ' ') {<br>array_push($this->_input_array, $temp_value);<br>}</p><p>// $this->_testInput();<br>print_r($this->_expression_value);<br>print_r($this->_input_array);<br>return $this->_input_array;<br>  }</p><p>  function _arrayToRpn() {</p><p>if ($this->_error  null) {<br>$this->_output = array();<br>return $this->_output;<br>}</p><p>for($i = 0; $i _input_array); $i++) {</p><p>$temp = $this->_input_array[$i];</p><p>if (is_numeric($temp)) {<br>  $this->_outputAdd($temp);<br>} else if($this->_keyExists($temp, $this->_expression_value, 0)) {<br>  $this->_outputAdd($this->_expression_value[$temp]);<br>} else {<br>  if ($temp == ')') {<br>while(!$this->_stackEmpty() && ($this->_stackPriority() >= 1)) {<br>$this->_outputAdd($this->_stackDelete());<br>}<br>if (!$this->_stackEmpty()) {<br>$this->_stackDelete();<br>}</p><p>  } elseif ($temp=='(') {<br>$this->_stackAdd($temp);<br>  } elseif (($this->_stackEmpty()) || (($this->_priority($temp) > </p><p>$this->_stackPriority()))) {<br>$this-> _stackAdd($temp);<br>  } else {<br>while(!$this->_stackEmpty() && ($this->_priority($temp) </p><p>_stackPriority())) {<br>$this->_outputAdd($this->_stackDelete());<br>}<br>$this->_stackAdd($temp);<br>  }</p><p>}</p><p>}</p><p>while(!$this->_stackEmpty()) {<br>$this->_outputAdd($this->_stackDelete());<br>}</p><p>return $this->_output;<br>}</p><p>function _rpnToValue() {</p><p>$time1 = $this->_getMicroTime();</p><p>if ($this->_error  null) {<br>$this->_value = null;<br>return $this->_value;<br>}</p><p>$this->_value = 0;<br>$temp = $this->_output;</p><p>do {<br>$pos = $this->_nextOperator($temp);</p><p>if ($pos == -1) {<br>  $this->_error = $this->_raiseError('Syntax error');<br>  $this->_value = null;<br>  return $this->_value;<br>}</p><p>$operator = $this->_operation[$temp[$pos]];<br>$arg = $operator[2];<br>$function = $operator[3];</p><p>if (($arg==2) && (!isset($temp[$pos-1]) || !is_numeric($temp[$pos-1]) || </p><p>!isset($temp[$pos-2]) || !is_numeric($temp[$pos-2]))) {<br>  $this->_error = $this->_raiseError('Syntax error');<br>  $this->_value = null;<br>  return $this->_value;<br>} elseif (($arg==1) && (!isset($temp[$pos-1]) || !is_numeric($temp[$pos-1]))) {<br>  $this->_error = $this->_raiseError('Syntax error');<br>  $this->_value = null;<br>  return $this->_value;<br>}</p><p>if(is_array($function)) {</p><p>  if($arg==2) $arg_array = array($temp[$pos-2],$temp[$pos-1]);<br>  elseif($arg==1) $arg_array = array($temp[$pos-1]);<br>  else $arg_array = array();</p><p>  if($function['type'] == 'userFunction') {<br>$this->_value = call_user_func_array($function['function'], $arg_array);<br>  } else {<br>$function_array = array(&$function['class'], $function['method']);<br>$this->_value = call_user_func_array($function_array, $arg_array);<br>  }<br>} else {<br>  $this->_value = $this->$function($temp, $pos);<br>}</p><p>if ($this->_isNan($this->_value)) {<br>  $this->_error = $this->_raiseError('NAN value');<br>  $this->_value = null;<br>  return $this->_value;<br>} elseif ($this->_isInfinite($this->_value)) {<br>  $this->_error = $this->_raiseError('Infinite value');<br>  $this->_value = null;<br>  return $this->_value;<br>} elseif (is_null($this->_value)) {<br>  return $this->_value;<br>}</p><p>$temp = $this->_refresh($temp, $pos, $arg, $this->_value);<br>} while(count($temp) > 1);</p><p>$this->_value = $temp[0];</p><p>$time2 = $this->_getMicroTime();</p><p>$this->_timer = $time2 - $time1;</p><p>return $this->_value;<br>  }</p>
 

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/446823.htmlTechArticleA netizen wrote to me about the issue of salary calculation with PHP. I talked about a method of calculating wages in a previous article, but it was just a clever way to use existing expression tools. Now...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn