Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务活动详情
一、题目描述
给定一个表达式,只有加减号、括号和数字,求其值。
二、思路分析
本题我们用了两个栈去处理,一个是数字栈,一个是符号栈,正常情况下,表达式的每一层(每遇到一对括号就认为是新的一层)只占一个坑位,新加一个数,就和前面的数处理、合并起来。
如果遇到了括号(也就是进入了更里面的一层),就暂时没办法合并了,只能都存起来;待到遇到右括号的时候,此时该层在数字栈中也只占一个坑位,直接把左括号踢出去就好了,踢出去之后需要和上一层已经占有坑位的那个数再合并一下。
这里有个巧合就是我写的时候为了处理每层第一个数是负数的情况,我先放置了一个 0,这也就巧合地保证了遇到右括号,和上一层合并的时候一定有一个数字能和它合并,避免了 ((1+1)) 的问题,不用再去判断上一层还是一个括号——即没有数字合并,然后出错的情况。
三、AC代码
class Solution {
public:
long long p=0,l=0,i=0,ck=0;
stack<long long> num;
stack<char> op;
// 计算一次
void cacl(){
char ch = op.top(); op.pop();
int y = num.top(); num.pop();
int x = num.top(); num.pop();
if (ch == '+') num.push(x+y);
if (ch == '-') num.push(x-y);
return;
}
int calculate(string s) {
// 初始时需要先放入一个零,处理符号在前面的情况
ck = 1;
num.push(0);
l=s.length();
long long now = 0;
while (i < l) {
int flag=0;
// ck用来标识我们放置了一个零,如果后面不是负号,就得补一个加号,不然符号就会错乱了
if (ck == 1) {
ck = 0;
if (s[i] != '-') op.push('+');
}
while (i < l & s[i]>='0' && s[i]<='9') {
now = now * 10 + s[i] - '0';
i++;
flag=1;
}
if (flag) {
num.push(now);
now = 0;
cacl();
}
if (s[i] == ' ') {
i++;
} else
if (s[i] == '(') {
num.push(0);
ck = 1;
op.push(s[i]);
i++;
} else
if (s[i] == ')') {
op.pop();
cacl();
i++;
} else {
op.push(s[i]);
i++;
}
}
long long ans= num.top();
return ans;
}
};
四、总结
与其说它是一道栈的题目,不如说它是道恶心人的大模拟。看看下面的图就知道我有多崩溃了,昨天写的时候一直解决不了负号在前面的情况,写了很多补丁,结果越写bug越多,很难受,索性停下来不写了(这也是我一个很好的经验,遇到一些烦人的东西,需要积极面对没错,但是!不要陷进去,感觉自己有点乱了就强制停下来休息,隔了一整天再继续想一想,一下子就解决了)