小光正在学习如何写一个编译器,但是他的代码能力还不够。
他希望,编译器能够正确识别出带有括号的常数加、减、乘、幂算式,并且直接计算出算式的结果,以此达到编译优化的目的。现在,他把识别出的算式交给了你,你需要帮助他完成计算的任务。
算式的定义 为了严谨,我们将使用类似于上下文无关文法的规则来定义算式 ? S :
任意非负整数 ? ( ? ≥ 0 ) n(n≥0),是一个算式。例如:0, 123, 1905, 1145141918210 等。 如果 ? A 是一个算式, ? B 是一个算式, ? ? op 是 - 、+、* 和 ^ 中的一种,那么 ?
? ?
? A op B 拼接在一起,也是一个算式。例如:1+1, 53+1, 2^2^2 等。 如果 ? A 是一个算式,那么 ( ? ) (A) 也是一个算式。例如,(12), ((137)-(4+12)), (((1+1))) 等。 运算符说明 请注意,因为小光的机器只提供 32 位二进制寄存器,任何一个运算符的运算结果,超出二进制32位的进位和借位统统忽略,因此你需要输出运算结果在 32 位无符号整形中的值。
#include<bits/stdc++.h>
using namespace std;
#define int unsigned int
string s;
int n;
stack<int> sti;
stack<char> stc;
int qpow(int x,int y){
int ans=1;
while(y){
if(y&1)ans*=x;
x*=x;y/=2;
}
return ans;
}
signed main(){
cin>>s;
s=" "+s;
n=s.size()-1;
for(int i=1;i<=n;i++){
if(s[i]>='0'&&s[i]<='9'){
int r=s[i]-'0';
while(i+1<=n&&s[i+1]>='0'&&s[i+1]<='9'){
r=r*10+s[i+1]-'0';i++;
}
sti.push(r);
}else if(s[i]=='+'||s[i]=='-'){
while(stc.size()&&(stc.top()=='*'||stc.top()=='^')){
int x=sti.top();sti.pop();
int y=sti.top();sti.pop();
if(stc.top()=='*')sti.push(x*y);
else sti.push(qpow(y,x));
stc.pop();
}
stc.push(s[i]);
}else if(s[i]=='*'){
while(stc.size()&&stc.top()=='^'){
int x=sti.top();sti.pop();
int y=sti.top();sti.pop();
sti.push(qpow(y,x));
stc.pop();
}
stc.push(s[i]);
}else if(s[i]==')'){
while(stc.size()&&stc.top()!='('){
int x=sti.top();sti.pop();
int y=sti.top();sti.pop();
if(stc.top()=='+'){
sti.push(x+y);
}else if(stc.top()=='-'){
sti.push(y-x);
}else if(stc.top()=='*')sti.push(x*y);
else sti.push(qpow(y,x));
stc.pop();
}
stc.pop();
}else stc.push(s[i]);
}
while(sti.size()>1){
int x=sti.top();sti.pop();
int y=sti.top();sti.pop();
if(stc.top()=='+'){
sti.push(x+y);
}else if(stc.top()=='-'){
sti.push(y-x);
}else if(stc.top()=='*')sti.push(x*y);
else sti.push(qpow(y,x));
stc.pop();
}
cout<<sti.top();
return 0;
}
20pts QWQ