CH1802 表达式计算4

Posted autoint

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CH1802 表达式计算4相关的知识,希望对你有一定的参考价值。

题意

给出一个表达式,其中运算符仅包含+,-,*,/,^(加 减 乘 整除 乘方)要求求出表达式的最终值

数据可能会出现括号情况,还有可能出现多余括号情况

数据保证不会出现>=2^31的答案

数据可能会出现负数情况

表达式总长度<=30

分析

参照机械能战士的题解。

此处不使用栈求表达式值的算法, 而使用递归算法, 注意题目中指出表达式中可能存在多余括号, 因此应首先去除多余括号得到等价的合法表达式(使用栈进行配对即可), 接下来将表达式长度视为问题的规模, 为减小问题的规模实现递归, 根据运算符优先级特点, 如果表达式中存在不在任何括号中的加减号, 那么将最后一个不在任何括号中的加减号作为表达式分割点, 如果存在表达式中存在不在任何括号中的乘除号, 那么将最后一个不在任何括号中的乘除号作为表达式分割点, 否则以最后一个不在任何括号中的乘方号作为表达式的分割点, 下面给出基于此思想AC代码(实际上, 可通过对表达式长度进行数学归纳, 证明下述程序能正确计算表达式的值, 具体证明过程此处不再赘述)

代码

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
using namespace std;

co int MAX=35,NIL=0x3f3f3f3f;
char cstr[MAX];
list<char> li;
vector<list<char>::iterator> ve;
vector<int> vee;
int getRes(int l,int r){
    int x=NIL,y=NIL,z=NIL;
    for(int i=l;i<=r;++i){
        if(cstr[i]=='(') vee.push_back(i);
        else{
            if(cstr[i]==')') vee.pop_back();
            else{
                if((cstr[i]=='+'||cstr[i]=='-')&&vee.empty()) x=i;
                else if((cstr[i]=='*'||cstr[i]=='/')&&vee.empty()) y=i;
                else if(cstr[i]=='^'&&vee.empty()) z=i;
            }
        }
    }
    if(x==NIL&&y==NIL&&z==NIL){
        if(cstr[l]=='(') return getRes(l+1,r-1);
        int res=0;
        for(int i=l;i<=r;++i)
            res=res*10+cstr[i]-'0';
        return res;
    }
    if(x!=NIL){
        if(cstr[l]=='-') return -getRes(l+1,r);
        else return cstr[x]=='+'?getRes(l,x-1)+getRes(x+1,r):getRes(l,x-1)-getRes(x+1,r);
    }
    if(y!=NIL) return cstr[y]=='*'?getRes(l,y-1)*getRes(y+1,r):getRes(l,y-1)/getRes(y+1,r);
    return pow((double)getRes(l,z-1),getRes(z+1,r));
}
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    int len=(scanf("%s",cstr+1),strlen(cstr+1));
    for(int i=1;i<=len;++i)
        li.push_back(cstr[i]);
    for(list<char>::iterator it=li.begin();it!=li.end();++it){
        if(*it=='(') ve.push_back(it);
        else if(*it==')'&&!ve.empty()) ve.pop_back();
    }
    for(int i=0;i<ve.size();++i)
        li.erase(ve[i]);
    copy(li.begin(),li.end(),cstr+1);
    len=li.size();
    printf("%d
",getRes(1,len));
    return 0;
}

以上是关于CH1802 表达式计算4的主要内容,如果未能解决你的问题,请参考以下文章

jsp基础语言-jsp代码段

4.3 合并重复的条件执行片段

为啥ip片段必须是8字节的倍数

计算机1802刘思源

10个JavaScript代码片段,使你更加容易前端开发。

10个JavaScript代码片段,使你更加容易前端开发。