Description
给定一个长度为\(n\)的表达式字符串\(s\),里面包含:' '
、[0-9]
、[+-()]
。求出表达式的最终结果。
Constraints
\(1 \le n \le 3 \times 10^5\)
Solution
使用递归下降即可。
expression -> term (('+' | '-') term)*
term -> factor (('*' | '/') factor)*
factor -> NUMBER | '(' expression ')'
总之对照上面的表复刻一下就好了,这里也顺便写了乘除法(下取整)。
为了代码整洁,这里需要抽象一个扫描控制器ctl
,使得读取任意字符前都过滤掉空格。
Code
class Solution {
public:
struct {
string s;
int pos;
void skip() { while(s[pos] == ' ') pos++; }
char peek() { return skip(), s[pos]; }
char pop() { return skip(), s[pos++]; }
bool accept(std::integral auto ...cs)
{ return ((peek() == cs) || ...); }
bool accept(std::invocable<char> auto ...conds)
{ return (conds(peek()) || ...); }
} ctl;
int calculate(string s) {
ctl.s = std::move(s);
ctl.pos = 0;
return expression();
}
int expression() {
auto ans = term();
while(ctl.accept('+', '-')) {
if(ctl.pop() == '+') ans += term();
else ans -= term();
}
return ans;
}
int term() {
auto ans = factor();
while(ctl.accept('*', '/')) {
if(ctl.pop() == '*') ans *= factor();
else ans /= factor();
}
return ans;
}
int factor() {
auto ans = number();
while(ctl.accept('(')) {
ctl.pop();
ans += expression();
ctl.pop();
}
return ans;
}
int number() {
int ans = 0;
while(ctl.accept(::isdigit)) {
auto c = ctl.pop();
ans = ans*10 + (c - '0');
}
return ans;
}
};