计蒜客 加减乘除

本文介绍了一种将中缀表达式转换为后缀表达式并计算其值的算法实现,适用于包含基本算术运算符(加减乘除幂)的表达式。该算法通过优先级比较来处理运算符,确保了计算的准确性。

点击打开链接

1000ms     65536K
给出一个表达式,其中运算符仅包含  + , - , * , / , ^ 要求求出表达式的最终值在这里, /  为整除最终结果为正整数,数据保证不需要使用高精度!

输入仅一行,即为表达式。

输出仅一行,既为表达式算出的结果 结果小于 long int 的最大范围,且整个计算的过程中,也不会超过 long int 的最大范围。

表达式总长度 \leq 2020

样例输入
2^3+1
样例输出
9

ac代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<stack>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define ll long long
using namespace std;

const int maxOp=6;

struct Pri
{
    char ch;
    ll pri;
}lpri[]={{'=',1},{'^',7},{'*',5},{'/',5},{'+',3},{'-',3}},
 rpri[]={{'=',1},{'^',6},{'*',4},{'/',4},{'+',2},{'-',2}};
ll Leftpri(char op)
{
    for(int i=0;i<maxOp;i++)
        if(lpri[i].ch==op)
            return lpri[i].pri;
}

ll Rightpri(char op)
{
    for(int i=0;i<maxOp;i++)
        if(rpri[i].ch==op)
            return rpri[i].pri;
}

bool IsOp(char ch)
{
    if(ch=='^'||ch=='*'||ch=='/'||ch=='+'||ch=='-')
        return true;
    return false;
}

int Precede(char op1,char op2)
{
    int lpri=Leftpri(op1);
    int rpri=Rightpri(op2);
    if(lpri==rpri)
        return 0;
    else if(lpri<rpri)
        return -1;
    else
        return 1;
}
void TransToPostExp(char* exp,char postExp[])
{
    stack<char>opStack;
    opStack.push('=');
    int i=0;
    while(*exp!='\0')
    {
        if(!IsOp(*exp))//不是运算符
        {
            while(*exp>='0'&&*exp<='9')
            {
                postExp[i++]=*exp;
                exp++;
            }
            postExp[i++]='#';
        }
        else
        {
            int cmpPri=Precede(opStack.top(),*exp);
            if(cmpPri==0)
            {
                opStack.pop();
                exp++;
            }
            else if(cmpPri==-1)
            {
                opStack.push(*exp);
                exp++;
            }
            else
            {
                while(Precede(opStack.top(),*exp)==1)
                {
                    postExp[i++]=opStack.top();
                    opStack.pop();
                }
            }
        }
    }
    while(opStack.top()!='=')
    {
        postExp[i++]=opStack.top();
        opStack.pop();
    }
    postExp[i]='\0';
}

void GetTwoFromStack(stack<int>& numStack,int& a,int& b)
{
    a=numStack.top();
    numStack.pop();
    b=numStack.top();
    numStack.pop();
}

ll Calfrompostexp(char* postExp)//计算后缀表达式
{
    stack<int>numStack;
    int a,b,w;
    while(*postExp!='\0')
    {
        switch(*postExp)
        {
        case '#':
            break;
        case '+':
            GetTwoFromStack(numStack,a,b);
            numStack.push(b+a);
            break;
        case '-':
            GetTwoFromStack(numStack,a,b);
            numStack.push(b-a);
            break;
        case '*':
            GetTwoFromStack(numStack,a,b);
            numStack.push(b*a);
            break;
        case '/':
            GetTwoFromStack(numStack,a,b);
            numStack.push(b/a);
            break;
        case '^':
            GetTwoFromStack(numStack,a,b);
            w=pow((double)b,(double)a);
            numStack.push(w);
            break;
        default:
            int n=0;
            while(*postExp >='0' && *postExp<='9')
            {
                n=n*10+(*postExp-'0');
                postExp++;
            }
            numStack.push(n);
            break;
        }
        postExp++;
    }
    return numStack.top();
}
char Exp[50];
char postExp[50];
int main()
{
    while(cin>>Exp)
    {
        TransToPostExp(Exp,postExp);
        cout<<Calfrompostexp(postExp)<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值