今天刷牛客遇到一个表达式求值的题,题目链接如下:
牛客NC137-表达式求值
这道题与Leetcode 224-基本计算器类似,但Leetcode这道题没有要求乘法
涉及到编译原理的内容,后缀表达式计算起来比较容易,复习了一下将中缀表达式转化为后缀表达式的方法。
①要用到两个stack:一个放数字、一个放运算符,由于数字可能有多位,且存在运算符栈顶pop后向数字栈push的情况,因此两个stack数据类型定义为string。
②由于放数字的栈存放最后后缀表达式,且需要一次弹出逆序,果断一开始就用queue来存储
因此,定义存放运算符的栈opS、存放数字(及最终逆波兰式)的队列numQ
转化过程结合代码如下,我是用C++写的
首先,对中缀表达式进行遍历:
int len=s.size();
for(int i=0;i<len;i++){
...
}
下面是重点,即for循环中...
的部分
①如果是数字,直接压入numQueue
//当前是数字
if(s[i]>='0' && s[i]<='9'){
string curNum="";
while(i<len && s[i]>='0' && s[i]<='9'){
curNum+=s[i];
i++;
}
numQ.push(curNum);
i--;
}
这里i--
是因为此时i已经指向非数字字符,要进行下一次循环,因为for有i++,为了不跳过当前字符先自减1
②如果是 ( :直接压入opStack
//当前是左括号
else if(s[i]=='(')
opS.push("(");
刚才提到了opS和numQ存放的都是string,注意push时用双引号
③如果是 ) :直到opStack栈顶为 ( 前,将栈顶弹出、并压入numQueue;直到栈顶为 ( 时,将左括号弹出
//当前是右括号
else if(s[i]==')'){
while(!opS.empty() && opS.top()!="("){
numQ.push(opS.top());
opS.pop();
}
//左括号要弹出来
opS.pop();
}
④如果是其他运算符( + - * ):
1. 如果opStack栈空 或 栈顶是( ,直接压入栈
2.如果当前运算符 s [ i ] 比 opSta