• 中缀表达式求值


    中缀表达式求值

    • 题目
      给出一个表达式,其中运算符仅包含+,-,*,/,^(加 减 乘 整除 乘方)要求求出表达式的最终值
      数据可能会出现括号情况,还有可能出现多余括号情况
      数据保证不会出现>=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;
    }
    
    
  • 相关阅读:
    ASP.NET Core 2.0 : 四. _Layout与_ViewStart
    [ASP.NET MVC 小牛之路]04
    [ASP.NET MVC 小牛之路]03
    [ASP.NET MVC 小牛之路]02
    [ASP.NET MVC 小牛之路]01
    Ext JS 4 的类系统
    生活沉思录 via 哲理小故事(一)
    ExtJS框架基础:事件模型及其常用功能
    ExtJS初探:了解 Ext Core
    ExtJS初探:在项目中使用ExtJS
  • 原文地址:https://www.cnblogs.com/Suiyue-Li/p/12563345.html
Copyright © 2020-2023  润新知