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的主要内容,如果未能解决你的问题,请参考以下文章