Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务活动详情
一、题目描述
给定一个bool表达式,如|(&(t,f,t),!(f)),求其值
数据范围
L <= 20000
二、思路分析
典型的字符串表达式的题目,但是之前写双栈操作(数字栈、符号栈)写麻了,所以换一个做法。
观察题目的表达式,每一层都很规范,非常适合写递归。所以这题也就变成了一个递归的大模拟,没什么思维难度,主要在于细节。
这里说几个自己被坑的点
一、切割字符串的时候没有判断层次
我们将第一层内的东西全部看成一个单位,所以我们要将他们切分开来,依次递归、保存,最后求值。这些东西是以逗号‘,’为分隔,但是每个单位里面还可能有逗号,如何判断当前遇到的括号是对应于最外层的用于分隔的逗号呢? 开个count记录一下层次就好了,左括号加一右括号减一,等于零的时候就是我们当前所在的最外的层次。
二、 s.substr()
该函数传参的时候加减号搞反了,单步调的时候才发现。这其实是挺累人的错误,临场的时候很难查出来。
三、
三、AC代码
class Solution {
public:
bool deal(string s) {
int l = s.length();
if (l==1) return s[0]=='t' ? true : false;
if (s[0]=='!') return !deal(s.substr(2, l-3));
vector<bool> f;
int last=1,count=0;
for (int i=2; i<l; i++){
if (s[i]=='(') count++;
if (s[i]==')') count--;
if ((s[i]==',' && count==0) || i==l-1) {
f.push_back(deal(s.substr(last+1, i-last-1)));
last = i;
}
}
int n = f.size();
for (int i=1; i<n; i++) {
if (s[0]=='|') f[0] = f[0] | f[i];
else f[0] = f[0] & f[i];
}
return f[0];
}
bool parseBoolExpr(string expression) {
return deal(expression);
}
};
四、总结
目前一共接触到了三题表达式的题目,要及时复习及时看,有些坑点真的是一言难尽,还是得注意细节与边界吧。在写之前最好能站在一个宏观的层面设计好布局,能省去很多微操调整的地方。