给出一个表达式,其中运算符仅包含+,-,*,/,^(加 减 乘 整除 乘方)要求求出表达式的最终值。
数据可能会出现括号情况,还有可能出现多余括号情况。
数据保证不会出现大于或等于231的答案。
数据可能会出现负数情况。
输入格式
输入仅一行,即为表达式。
输出格式
输出仅一行,既为表达式算出的结果。
输入样例:
(2+2)^(1+1)
输出样例:
16
这道题应用栈来将它解决掉,不要看代码长,只要理解了就不难了。首先一个计算式中含有数字和操作符,我们要建立两个栈,一个栈存放数字,一个栈存放操作符。例如这和计算式,1-2*3。因为乘号的优先级别大于减号,所以我们不能先计算1-2,这样是错的,所以我们在计算的时候就要判断,我们先去一个计算符号,如果前一个计算符号的优先级是不是大于现在的计算符号的优先级,那么我们就不能进行前面的计算,只能将符号入栈。如果前一个的优先级和现在的优先级相等或者大于现在的优先级,那么我们就要取出数字栈中的两个数字和一个操作符进行运算。
#include<iostream>
#include<stack>
using namespace std;
stack<int> num;//数字栈
stack<int> op;//操作栈
void cal()
{
int a=num.top();num.pop();//a,b分别为数字栈中的前两个值
int b=num.top();num.pop();
char c=op.top();op.pop();//栈顶的运算符号
int d;
if(c=='+')//分别对美中操作进行计算,然后将计算完的值继续入栈
d=a+b;
if(c=='-')//这里一定是b-a,因为b是a前面的数字,
d=b-a;
if(c=='*')
d=a*b;
if(c=='/')
d=b/a;
if(c=='^')
{
d=1;
while(a--)
{
d*=b;
}
}
num.push(d);
}
int main()
{
string str;
cin>>str;
string left;//在计算式的左边加入符号,因为表达式中呢可能有多余的括号,所以要让左括号多余右括号
for(int i=0;i<str.size();i++)//有多少个字符就有多少个左括号
left+='(';
str=left+str+')';//和计算表达式合并在一起
for(int i=0;i<str.size();i++)//开始遍历每一个字符
{
if(str[i]>='0'&&str[i]<='9')//判断是否是数字,是数字就加入数字栈
{
int j=i,t=0;
while(str[j]>='0'&&str[j]<='9')//因为不一定是以为的数字,所以要判断
{
t=t*10+str[j]-'0';
j++;
}
i=j-1;
num.push(t);//将计算得到数字加入栈
}
else
{
char c=str[i];//判断是哪种操作符
if(c=='+'||c=='-')
{
if(c=='-'&&i&&!(str[i-1]>='0'&&str[i-1]<='9'||str[i-1]==')'))//z这里判断是不是负数
{
int j=i+1,t=0;
while(str[j]>='0'&&str[j]<='9')
{
t=t*10+str[j]-'0';
j++;
}
i=j-1;
num.push(-t);//如果是负数,就把负数加入数字栈
}
else
{
while(op.top()!='(')//操作符栈中只要不是(就进行计算
cal();
op.push(c);
}
}
else if(c=='*'||c=='/')
{
while(op.top()=='*'||op.top()=='/'||op.top()=='^') cal();//如果当前操作符的前一个操作符是这三种就当前操作符前面的数进行运算
op.push(c);
}
else if(c=='^')
{
while(op.top()=='^') cal();//根据优先级别,只有是‘^’时,擦能计算前面
op.push(c);
}
else if(c==')')
{
while(op.top()!='(')
cal();
op.pop();
}
else if(c=='(')
op.push(c);
}
}
cout<<num.top();//通过计算,最后栈中只剩下这一个数字,就是最终的结果
return 0;
}