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 ] == ' F ' )) {
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
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 ] == ' F ' )) {
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