PHP逆波兰表达式的算法

  1  - 工资计算专用 
  2 
  3    关于PHP计算工资问题。以下一篇文章中谈到一种计算工资的方法,称作逆波兰的算法。 
  4 
  5          我们的目标是实现如下的计算公式: 
  6 
  7          假设有一个计算公式如下:   
  8 
  9           $expression     =     " (F1*F12+10.34)  "
 10 
 11          其中的变量值如下: 
 12 
 13           $expression_value     =     Array ' F1  ' =>   10 ,   ' F12  ' =>   20 ); 
 14 
 15          我们希望用PHP构建一个类来计算出这个表达式的值。这种应用主要用于web工资管理中,用户可以自定义其工资相公式的情况 
 16 
 17           $rpn     =     new    Math_Rpn(); 
 18           $rpn ->  setExpressionValue( $expression_value );     
 19           echo     $rpn ->  calculate( $expression ,   ' deg  ' , false );    //    即为相应的值 
 20 
 21          解析逆波兰表达式的方法,编译原理中有,就是先把表达式分解成符号数组,然后求逆波兰式,最后根据逆波兰式得到其结果。 
 22 
 23    我分别把三个函数贴在下面,其实本质我就是对Pear的RPN函数进行了Hack .  
 24 
 25           function    _stringToArray   ()   { 
 26           $temp_operator     =     null
 27           $temp_value     =     null
 28 
 29           $this ->  _input    =     str_replace "     " ,   "   " , $this ->  _input); 
 30 
 31           for ( $i     =     0 ;    $i     <     strlen ( $this ->  _input);    $i ++ )   { 
 32           if    ( $this ->  _input[ $i ]    ==     '     ' )   { 
 33               if    ( $temp_operator     !=     null )   { 
 34           array_push ( $this ->  _input_array ,     $temp_operator ); 
 35           $temp_operator     =     null
 36              } 
 37               if    ( $temp_value     !=     null )   { 
 38           array_push ( $this ->  _input_array ,     $temp_value ); 
 39           $temp_value     =     null
 40              } 
 41          }    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 ]    ==     ' ' ))   { 
 42               if    ( $temp_operator     !=     null )   { 
 43           array_push ( $this ->  _input_array ,     $temp_operator ); 
 44           $temp_operator     =     null
 45              } 
 46 
 47               array_push ( $this ->  _input_array ,     ' -1  ' ); 
 48               array_push ( $this ->  _input_array ,     ' ' ); 
 49           // }   elseif   ((is_numeric($this-> _input[$i]))   ||   ($this-> _input[$i]   ==   '. '))   { 
 50          }    elseif    (( is_numeric ( $this ->  _input[ $i ]))    ||    ( $this ->  _input[ $i ]    ==     ' ' )    ||    ( $this ->  _input[ $i ]    ==     ' ' ))   { 
 51               if    ( $temp_operator     !=     null )   { 
 52           array_push ( $this ->  _input_array ,     $temp_operator ); 
 53           $temp_operator     =     null
 54              } 
 55 
 56               $temp_value     .=     $this ->  _input[ $i ]; 
 57          }    else    { 
 58               if    ( $this ->  _keyExists( $temp_operator ,     $this ->  _operation ,     1 ))   { 
 59           array_push ( $this ->  _input_array ,     $temp_operator ); 
 60           $temp_operator     =     null
 61              } 
 62 
 63               if    ( $temp_value     !=     null )   { 
 64           array_push ( $this ->  _input_array ,     $temp_value ); 
 65           $temp_value     =     null
 66              } 
 67 
 68               $temp_operator     .=     $this ->  _input[ $i ]; 
 69          } 
 70          } 
 71 
 72           if    ( $temp_operator     !=     null     &&     $temp_operator     !=     '     ' )   { 
 73           array_push ( $this ->  _input_array ,     $temp_operator ); 
 74          }    elseif ( $temp_value     !=     null     &&     $temp_value     !=     '     ' )   { 
 75           array_push ( $this ->  _input_array ,     $temp_value ); 
 76          } 
 77 
 78           //    $this-> _testInput(); 
 79           print_r ( $this ->  _expression_value); 
 80           print_r ( $this ->  _input_array); 
 81           return     $this ->  _input_array; 
 82              } 
 83 
 84               function    _arrayToRpn()   { 
 85 
 86           if    ( $this ->  _error    <>     null )   { 
 87           $this ->  _output    =     array (); 
 88           return     $this ->  _output; 
 89          } 
 90 
 91           for ( $i     =     0 ;    $i     <     count ( $this ->  _input_array);    $i ++ )   { 
 92 
 93           $temp     =     $this ->  _input_array[ $i ]; 
 94 
 95           if    ( is_numeric ( $temp ))   { 
 96               $this ->  _outputAdd( $temp ); 
 97          }    else     if ( $this ->  _keyExists( $temp ,     $this ->  _expression_value ,     0 ))   { 
 98               $this ->  _outputAdd( $this ->  _expression_value[ $temp ]); 
 99          }    else    { 
100               if    ( $temp     ==     ' ' )   { 
101           while ( ! $this ->  _stackEmpty()    &&    ( $this ->  _stackPriority()    >   =     1 ))   { 
102           $this ->  _outputAdd( $this ->  _stackDelete()); 
103          } 
104           if    ( ! $this ->  _stackEmpty())   { 
105           $this ->  _stackDelete(); 
106          } 
107 
108              }    elseif    ( $temp ==   ' ' )   { 
109           $this ->  _stackAdd( $temp ); 
110              }    elseif    (( $this ->  _stackEmpty())    ||    (( $this ->  _priority( $temp )    >     $this ->  _stackPriority())))   { 
111           $this ->    _stackAdd( $temp ); 
112              }    else    { 
113           while ( ! $this ->  _stackEmpty()    &&    ( $this ->  _priority( $temp )    <=     $this ->  _stackPriority()))   { 
114           $this ->  _outputAdd( $this ->  _stackDelete()); 
115          } 
116           $this ->  _stackAdd( $temp ); 
117              } 
118 
119          } 
120 
121          } 
122 
123           while ( ! $this ->  _stackEmpty())   { 
124           $this ->  _outputAdd( $this ->  _stackDelete()); 
125          } 
126 
127           return     $this ->  _output; 
128          } 
129 
130           function    _rpnToValue()   { 
131 
132           $time1     =     $this ->  _getMicroTime(); 
133 
134           if    ( $this ->  _error    <>     null )   { 
135           $this ->  _value    =     null
136           return     $this ->  _value; 
137          } 
138 
139           $this ->  _value    =     0
140           $temp     =     $this ->  _output; 
141 
142           do    { 
143           $pos     =     $this ->  _nextOperator( $temp ); 
144 
145           if    ( $pos     ==     - 1 )   { 
146               $this ->  _error    =     $this ->  _raiseError(  ' Syntax   error  ' ); 
147               $this ->  _value    =     null
148               return     $this ->  _value; 
149          } 
150 
151           $operator     =     $this ->  _operation[ $temp [ $pos ]]; 
152           $arg     =     $operator [ 2 ]; 
153           $function     =     $operator [ 3 ]; 
154 
155           if    (( $arg == 2 )    &&    ( ! isset ( $temp [ $pos - 1 ])    ||     ! is_numeric ( $temp [ $pos - 1 ])    ||     ! isset ( $temp [ $pos - 2 ])    ||     ! is_numeric ( $temp [ $pos - 2 ])))   { 
156               $this ->  _error    =     $this ->  _raiseError(  ' Syntax   error  ' ); 
157               $this ->  _value    =     null
158               return     $this ->  _value; 
159          }    elseif    (( $arg == 1 )    &&    ( ! isset ( $temp [ $pos - 1 ])    ||     ! is_numeric ( $temp [ $pos - 1 ])))   { 
160               $this ->  _error    =     $this ->  _raiseError(  ' Syntax   error  ' ); 
161               $this ->  _value    =     null
162               return     $this ->  _value; 
163          } 
164 
165           if ( is_array ( $function ))   { 
166 
167               if ( $arg == 2 )    $arg_array     =     array ( $temp [ $pos - 2 ] , $temp [ $pos - 1 ]); 
168               elseif ( $arg == 1 )    $arg_array     =     array ( $temp [ $pos - 1 ]); 
169               else     $arg_array     =     array (); 
170 
171               if ( $function ' type  ' ]    ==     ' userFunction  ' )   { 
172           $this ->  _value    =     call_user_func_array ( $function ' function  ' ] ,     $arg_array ); 
173              }    else    { 
174           $function_array     =     array ( & $function ' class  ' ] ,     $function ' method  ' ]); 
175           $this ->  _value    =     call_user_func_array ( $function_array ,     $arg_array ); 
176              } 
177          }    else    { 
178               $this ->  _value    =     $this ->   $function ( $temp ,     $pos ); 
179          } 
180 
181           if    ( $this ->  _isNan( $this ->  _value))   { 
182               $this ->  _error    =     $this ->  _raiseError(  ' NAN   value  ' ); 
183               $this ->  _value    =     null
184               return     $this ->  _value; 
185          }    elseif    ( $this ->  _isInfinite( $this ->  _value))   { 
186               $this ->  _error    =     $this ->  _raiseError(  ' Infinite   value  ' ); 
187               $this ->  _value    =     null
188               return     $this ->  _value; 
189          }    elseif    ( is_null ( $this ->  _value))   { 
190               return     $this ->  _value; 
191          } 
192 
193           $temp     =     $this ->  _refresh( $temp ,     $pos ,     $arg ,     $this ->  _value); 
194          }    while ( count ( $temp )    >     1 ); 
195 
196           $this ->  _value    =     $temp [ 0 ]; 
197 
198           $time2     =     $this ->  _getMicroTime(); 
199 
200           $this ->  _timer    =     $time2     -     $time1
201 
202           return     $this ->  _value; 
203              } 
204 

转载于:https://www.cnblogs.com/voswin/articles/1497291.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值