NYOJ35

题目大意:

传送门:点我传送

我的理解:

逆波兰表达式求解本题;




我的代码:

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值