中缀表达式求值
Posted suiyue-li
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了中缀表达式求值相关的知识,希望对你有一定的参考价值。
中缀表达式求值
- 题目
给出一个表达式,其中运算符仅包含+,-,*,/,^(加 减 乘 整除 乘方)要求求出表达式的最终值
数据可能会出现括号情况,还有可能出现多余括号情况
数据保证不会出现>=2^31的答案
数据可能会出现负数情况 - 输入: (2+2)^(1+1)
- 输出 :16
解题思路:
中缀表达式就是通用的算术或逻辑公式表示方法。
形如 ((1+2)-3) ,((a+b) imes c-d) 等;
显然用字符串读入后不便于计算结果,我们考虑把它转为后缀表达式。
如:我们平时写 (a+b),这是中缀表达式,写成后缀表达式就是:(ab+) ,
((a+b)*c-(a+b)/e)的后缀表达式为: (ab+c*ab+e/-) 这样做有什么好处?
我们可以通过使用两个栈(一个存储数值 (q_1),一个存储运算符号 (q_2))轻松求出结果。
那么如何得到后缀表达式?
-
我们假定优先级 (( < )<) 其他运算符
-
对输入的中缀表达式从左到右遍历:
-
如果遇到数字,直接添加到后缀表达式末尾;
-
如果遇到运算符:
先判断栈是否为空。若是,则直接将此运算符压入栈。若不是,则查看当前栈顶元素。不断地取出栈顶元素,若栈顶元素优先级 (geq) 此操作符级别,则弹出栈顶元素,将栈顶元素添加到后缀表达式中,否则结束循环。要注意的是,经过上述步骤,这个运算符最终一定会入栈。 -
字符串遍历结束后,如果栈不为空,则弹出栈中所有元素,将它们添加到后缀表达式的末尾,直到栈为空。
更一般的,我们一般把求后缀表达式和计算同时进行,遍历字符串,如果是数字,直接放入 (q_1) ,如果是运算符,那么我们不断取出 (q_2) 栈顶的运算符与 (S[i])比较(优先级),如果 (geq) 就拿出(q_1) 栈顶的两个元素做(q_2) 栈顶的运算,直到 (S[i]) 为栈内优先级最高的元素。最后得到的(q_1) 必然只有一个元素即答案。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N=110;
char s[N];
stack<int> q1,q2;
int qpow(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)
{
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=qpow(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]=‘)‘;
for(int i=0;i<=len;i++)
{
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
",q2.top());
return 0;
}
以上是关于中缀表达式求值的主要内容,如果未能解决你的问题,请参考以下文章