zoukankan      html  css  js  c++  java
  • 中缀表达式求值

    中缀表达式求值

    • 题目
      给出一个表达式,其中运算符仅包含+,-,*,/,^(加 减 乘 整除 乘方)要求求出表达式的最终值
      数据可能会出现括号情况,还有可能出现多余括号情况
      数据保证不会出现>=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;
    }
    
    
  • 相关阅读:
    批量新增百万条数据 十百万条数据
    sqlserver 组内排序
    EF ++属性会更新实体
    Entity Framework Core: A second operation started on this context before a previous operation completed
    abp Cannot access a disposed object. A common cause of this error is disposing
    abp xunit Can not register IHostingEnvironment. It should be a non-abstract class. If not, it should be registered before.”
    hangfire enqueued but not processing(hangfire 定时任务入队列但不执行)
    EF 更新实体 The instance of entity type 'BabyEvent' cannot be tracked because another instance
    datatable to entiy list 不支持可空类型和枚举类型
    webapi 设置不显示接口到swaggerUI
  • 原文地址:https://www.cnblogs.com/Suiyue-Li/p/12563345.html
Copyright © 2011-2022 走看看