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 
posted on 2009-06-05 22:30  睿达团队  阅读(403)  评论(0编辑  收藏  举报