1+ <?php
2+
3+
4+
5+ // 四则运算 +-*/()
6+ function expression ($ str )
7+ {
8+ $ str = str_replace (' ' ,'' ,$ str );
9+ $ arr = preg_split ('/([\+\-\*\/\(\)])/ ' , $ str , -1 , PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
10+
11+ $ numStack = []; // 存放数字
12+ $ operStack = []; // 存放运算符
13+ $ operStack [] = NULL ;
14+
15+ for ($ i = 0 ; $ i < count ($ arr ); $ i ++){
16+ if (ord ($ arr [$ i ]) >= 48 && ord ($ arr [$ i ] <= 57 )){
17+ array_push ($ numStack , $ arr [$ i ]);
18+ continue ;
19+ }
20+ switch ($ arr [$ i ]){
21+ case '+ ' :
22+ case '- ' :
23+ $ arrLen = count ($ operStack );
24+ while ($ operStack [$ arrLen -1 ] === '* ' || $ operStack [$ arrLen -1 ] === '/ ' || $ operStack [$ arrLen -1 ] === '- ' ){
25+ compute ($ numStack , $ operStack );
26+ $ arrLen --;
27+ }
28+ array_push ($ operStack , $ arr [$ i ]);
29+ break ;
30+ case '* ' :
31+ case '/ ' :
32+ case '( ' :
33+ array_push ($ operStack , $ arr [$ i ]);
34+ break ;
35+ case ') ' :
36+ $ arrLen = count ($ operStack );
37+ while ($ operStack [$ arrLen -1 ] !== '( ' ){
38+ compute ($ numStack , $ operStack );
39+ $ arrLen --;
40+ }
41+ array_pop ($ operStack );
42+ break ;
43+ default :
44+ throw new \Exception ("不支持的运算符 " , 1 );
45+ break ;
46+ }
47+ }
48+
49+ $ arrLen = count ($ operStack );
50+ while ($ operStack [$ arrLen -1 ] !== NULL ){
51+ compute ($ numStack , $ operStack );
52+ $ arrLen --;
53+ }
54+ echo array_pop ($ numStack );
55+ }
56+
57+ //数字栈长度减一,运算符栈长度减一
58+ function compute (&$ numStack , &$ operStack ){
59+ $ num = array_pop ($ numStack );
60+ switch (array_pop ($ operStack )) {
61+ case '* ' :
62+ array_push ($ numStack , array_pop ($ numStack ) * $ num );
63+ break ;
64+ case '/ ' :
65+ array_push ($ numStack , array_pop ($ numStack ) / $ num );
66+ break ;
67+ case '+ ' :
68+ array_push ($ numStack , array_pop ($ numStack ) + $ num );
69+ break ;
70+ case '- ' :
71+ array_push ($ numStack , array_pop ($ numStack ) - $ num );
72+ break ;
73+
74+ }
75+ }
76+ expression ('-1+2-(1+2*3) ' );
77+ echo PHP_EOL ;
78+ eval ('echo -1+2-(1+2*3); ' );
0 commit comments