题目描述
给出一个表达式,其中运算符仅包含
+,-,*,/,^
(加 减 乘 整除 乘方)要求求出表达式的最终值。
数据可能会出现括号情况,还有可能出现多余括号情况。
数据保证不会出现大于或等于$2^{31}$的答案。
数据可能会出现负数情况。
输入格式
输入仅一行,即为表达式。
输出格式
输出仅一行,既为表达式算出的结果。
样例
输入样例:
(2+2)^(1+1)
输出样例:
16
模拟+栈
其实就是不断的模拟四则运算,不过要记住,括号的运算级别是最低的,而不是最高的,和普通运算不一样,因为我们是在通过栈去模拟,一旦遇到括号,我们就要将括号外面的值都算完,所以括号等级要最低,否则将会出错,具体思想可见代码模拟.
C++ 代码
#include <bits/stdc++.h>
using namespace std;
#define fir(i,a,b) for(int i=a;i<=b;i++)
const int N=110;
char s[N];
stack<int> q1,q2;
int power(int a,int b)//快速幂求值
{
int ans=1;
while(b)
{
if (b&1)
ans=ans*a;
a*=a;
b>>=1;
}
return ans;
}
int check(char c) //check算出等级,记住要+,-虽然是同等级,但是我们一样还是设为不同等级,因为不然不好计算值,但是排序中是同等级的.
{
if(c=='(')
return -2;
if(c==')')
return -1;
if(c=='^')
return 5;
if(c=='*')
return 4;
if(c=='/')
return 3;
if(c=='+')
return 2;
if(c=='-')
return 1;
return 0;
}
int calc(int x)
{
int a,b;
b=q2.top();
q2.pop();
if(q2.empty() && x==1)
a=0;
else
{
a=q2.top();
q2.pop();
}
if(x==2)
return a+b;
if(x==1)
return a-b;
if(x==4)
return a*b;
if(x==3)
return a/b;
if(x==5)
{
int ans=power(a,b);
return ans;
}
}
bool cmp(int x,int y)
{
if(x&1) //+,-同等级 *,/同等级,(,)同等级
x++;
if(y&1) //+,-同等级 *,/同等级,(,)同等级 这里是将等级一致
y++;
return x>=y;
}
int main()
{
scanf("%s",s+1);
int len=strlen(s+1),x=0,y,z;
s[0]='(';
s[++len]=')';
fir(i,0,len)
{
y=check(s[i]);
if(!y) //数字
{
x=x*10+s[i]-'0';
continue;
}
if(!check(s[i-1]) && i) //符号
{
q2.push(x);
x=0;
}
if(y==-1) //是右括号,说明开始括号内计算.
{
z=q1.top();q1.pop();
while(z!=-2) //如果不是左括号,不断处理内部的运算
{
q2.push(calc(z));
z=q1.top();
q1.pop();
}
continue;
}
if(y!=-2) //不是左括号
{
while(!q1.empty() && cmp(q1.top(),y))//不断地运算,也就是将运算栈中的所有符号,开始运算
{
z=q1.top();
q1.pop();
q2.push(calc(z));
}
}
q1.push(y);
}
printf("%d\n",q2.top());
return 0;
}
ntt
有一个想法,与其说是括号优先级别最低,不如说右括号优先级别最低,左括号优先级别最高。
因为这里所谓的优先级别,实质上就是运算符的出栈顺序,如果比前面的运算符优先级高就不出栈,相等或低就出栈;右括号出现时一定要直接出栈,所以优先级最低;左括号出现一定不出栈,所以优先级最高。
(+怎么办?你括号后面不跟上符号的吗?
+-应该属于同一等级的吧
啊这让我想到了编译原理,搞一个语法树来算
hack数据:(-1)))
(不要觉得这个数据不合法,此题有((((-1)的数据)
强啊,感谢您的贡献。
但是这个数据表达确实不合法呀
这个数据现在测试数据里面有了,秦佬这份代码直接 Segmentation Fault
我的AC代码:
感谢!
问一下这样一组数据是否合法呢
(2+2)^(()-1+2)
如果合法,那么“前面是左括号就把负数计算出来”这个条件就错了
这个应该不合法吧hh,括号里面怎么能够没有数呢?
大佬这个代码好像还是有点问题。比如这组数据:1+(((2+3),来源是题目的新测试点。尾括号扫完1还是没有被计算进去。应该再特判一下如果还有数在后面手动加后括号。
hack数据: (-1-1)
%%%