题目大意:
传送门:点我传送
我的理解:
逆波兰表达式求解本题;
我的代码:
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
//判断运算符优先级
int judge(char ch){
switch(ch){
case '+':
case '-': return 1;
case '*':
case '/': return 2;
default : return 0;
}
}
//由中序表达式转换为后序表达式
void change(string &s1,string &s2){
stack<char> s;
s.push('#'); //作为栈底标记,用于判断栈中的符号是否全部输出
int i = 0; //作为移动在s1上的索引
while(i < s1.length()-1){
if(s1[i] == '('){ //只要碰到'('就直接进栈(因为其进栈以前优先级可认为最高),进栈以后其优先级最低
s.push(s1[i++]);
}else if(s1[i] == ')'){
while(s.top() != '('){
s2+=s.top();
s2+=' '; //此处及以后的空格是为了使数字与符合分离
s.pop();
}
s.pop(); //用于删除'('
i++;
}else if(s1[i] == '+' || s1[i] == '-' || s1[i] == '*' || s1[i] == '/'){
while(judge(s.top()) >= judge(s1[i])){ //当栈顶符号优先级高于或等于当前符号优先级时
s2+=s.top(); //则输出栈顶符号
s2+=' ';
s.pop();
}
s.push(s1[i]); //将当前符号压入栈中
i++;
}else{
while(s1[i] >= '0' && s1[i] <= '9' || s1[i] == '.'){
s2+=s1[i++];
}
s2+=' ';
}
}
while(s.top() != '#'){ //确保将所有符号都输出
s2+=s.top();
s2+=' ';
s.pop();
}
}
//由后序表达式计算出结果
double value(string s2){
stack<double> s;
double x,y;
int i = 0;
while(i < s2.length()){
if(s2[i] == ' '){
i++;
continue;
}
switch(s2[i]){
case '+': x = s.top();s.pop();x+=s.top();s.pop();i++;break;
case '-': x = s.top();s.pop();x=s.top()-x;s.pop();i++;break;
case '*': x = s.top();s.pop();x*=s.top();s.pop();i++;break;
case '/': x = s.top();s.pop();x=s.top()/x;s.pop();i++;break;
default:{
x = 0;
while('0' <= s2[i] && s2[i]<='9'){
x = x*10+s2[i]-'0';
i++;
}
if(s2[i] == '.'){
double t = 10.0;
y = 0;
i++;
while('0' <= s2[i] && s2[i] <= '9'){
y += ((s2[i]-'0')/t);
i++;
t*=10;
}
x+=y;
}
}
}
s.push(x);
}
return s.top();
}
int main(){
freopen("D:/OJ/挑战程序设计竞赛/NYOJ35.txt","r",stdin);
int n;
string s1,s2;
cin>>n;
while(n--){
cin>>s1;
s2="";
change(s1,s2);
double result = value(s2);
printf("%.2f\n",result);
}
return 0;
}