数学表达式求值:输入由数字、‘+’,‘—’,‘*’,‘/’,乘方’^’,小括号组成的字符串,输出运算结果;
使用栈实现。对于括号,预处理每个左括号对应的右括号位置,然后递归处理每个括号.对于判断负数要很小心,万一出现 -(-(-(-1)))
这种情况
#include<bits/stdc++.h>
using namespace std;
const int N=105;
char s[N];
int t[N],n;
unordered_map<char,int>mp;
void init() {
scanf("%s",s+1);
stack<int>tmp;
n=strlen(s+1);
for(int i=1; i<=n; ++i) {
if(s[i]=='(')
tmp.push(i);
else if(s[i]==')') {
t[tmp.top()]=i;
tmp.pop();
}
}
mp['+']=mp['-']=1;
mp['*']=mp['/']=2;
mp['^']=3;
}
bool isd(char c) {
return (c>='0'&&c<='9')?true:false;
}
void js(stack<char>&a,stack<double>&b)
{
double x=b.top();b.pop();
double y=b.top();b.pop();
char c=a.top();a.pop();
if(c=='+')b.push(y+x);
if(c=='-')b.push(y-x);
if(c=='*')b.push(y*x);
if(c=='/')b.push(y/x);
if(c=='^')b.push(pow(y,x));
}
double dfs(int l,int r) {
stack<char>s1;
stack<double>s2;
double neg=1;
for(int i=l; i<=r;) {
if(isd(s[i])) {
double tmp=0;
while(isd(s[i]))tmp=tmp*10+(s[i]-'0'),++i;
if(s[i]=='.') {
++i;
double sum=1;
while(isd(s[i]))sum/=10,tmp+=sum*(s[i]-'0'),++i;
}
tmp*=neg,neg=1;
s2.push(tmp);
} else if(s[i]=='(') {
s2.push(dfs(i+1,t[i]-1));
i=t[i]+1;
}
else {
if(s[i]=='-'&&isd(s[i+1])&&(i==1||((s[i-1]!=')'&&!isd(s[i-1]))))) {
neg=-1,++i;
continue;
}
if(!s1.empty()) {
while(s1.size()&& mp[s1.top()]>= mp[s[i]])js(s1,s2);
s1.push(s[i]);
}
else s1.push(s[i]);
++i;
}
}
while(s1.size())js(s1,s2);
return s2.top();
}
int main() {
init();
printf("%.3lf\n",dfs(1,n));
return 0;
}