PHP——表达式求值

表达式求值

设置一个操作数栈,设置一个操作符栈
分析字符串,操作数和操作符分别入栈,如果当前操作符优先级高于栈尾操作符优先级,则先计算栈尾操作符,再把当前操作符号入栈
最后把两个栈依次出栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
class StrToValue
{
private static $operatorLevel = [
'**' => 0,
'++' => 1,
'--' => 1,
'~' => 1,
'*' => 2,
'/' => 2,
'%' => 2,
'+' => 3,
'-' => 3,
'<<' => 4,
'>>' => 4,
'&' => 5,
'^' => 6,
'|' => 7,
'=' => 8,
'+=' => 8,
'-=' => 8,
'*=' => 8,
'**=' => 8,
'/=' => 8,
'.=' => 8,
'%=' => 8,
'&=' => 8,
'|=' => 8,
'^=' => 8,
'<<=' => 8,
'>>=' => 8,
];

private static $full = [
'~',
'*',
'/',
'%',
'+',
'-',
];

private static $nums = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];

/**
* @param $str
* @return array
* @throws Exception
*/
public static function calculate($str)
{
$len = strlen($str);
$numStack = $operatorStack = [];

$num = 0;
$operator = '';

$isNum = $isOperator = false;
$operators = array_keys(self::$operatorLevel);
// 分析字符串入栈
for ($i = 0; $i < $len; $i++) {
if ($str[$i] === ' ') {
continue;
}
if (in_array($str[$i], self::$nums, true)) {
if ($isNum) {
$num .= $str[$i];
} else {
$num = $str[$i];
if (count($operatorStack) > 0) {
$op = array_pop($operatorStack);
if (self::$operatorLevel[$op] > self::$operatorLevel[$operator]) {
$operatorStack[] = $op;
$operatorStack[] = $operator;
} else if (count($numStack) > 0) {
$right = array_pop($numStack);
$left = array_pop($numStack);
$aaa = 'return ' . ($left ?? '') . $op . $right . ';';
$numStack[] = eval($aaa);
$operatorStack[] = $operator;
}
} else if ($isOperator !== false) {
$operatorStack[] = $operator;
}
}
$isNum = true;
$isOperator = false;
} else if (in_array($str[$i], $operators, true)) {
if ($isOperator) {
$operator .= $str[$i];
} else {
$operator = $str[$i];
if ($isNum === false) {
$numStack[] = !in_array($operator, self::$full, true) ? '' : 0;
} else {
$numStack[] = $num;
}
}

$isNum = false;
$isOperator = true;
} else {
throw new Exception($str . '包含无效的字符' . $str[$i]);
}
}
if ($isNum) {
$numStack[] = $num;
}
if ($isOperator) {
$operatorStack[] = $operator;
}
// 计算结果(出栈)
while (!empty($operatorStack)) {
$right = array_pop($numStack);
$left = array_pop($numStack);
$op = array_pop($operatorStack);
$numStack[] = eval('return ' . $left . $op . $right . ';');
}
return $numStack[0];
}
}
文章不错,你都不请我喝杯茶,就是说你呀!
0%
upyun