码迷,mamicode.com
首页 > 其他好文 > 详细

中缀表达式求值

时间:2020-03-25 00:51:04      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:方法   数字   stack   字符   查看   通用   ret   表达式求值   top   

中缀表达式求值

  • 题目
    给出一个表达式,其中运算符仅包含+,-,*,/,^(加 减 乘 整除 乘方)要求求出表达式的最终值
    数据可能会出现括号情况,还有可能出现多余括号情况
    数据保证不会出现>=2^31的答案
    数据可能会出现负数情况
  • 输入: (2+2)^(1+1)
  • 输出 :16

解题思路:

中缀表达式就是通用的算术或逻辑公式表示方法。
形如 \((1+2)-3\)\((a+b)\times 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\n",q2.top());
    return 0;
}

中缀表达式求值

标签:方法   数字   stack   字符   查看   通用   ret   表达式求值   top   

原文地址:https://www.cnblogs.com/Suiyue-Li/p/12563345.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!