nyoj 267 郁闷的C小加(二)中缀表达式变后缀表达式并计算值

郁闷的C小加(二)

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 4
描述

聪明的你帮助C小加解决了中缀表达式到后缀表达式的转换(详情请参考“郁闷的C小加(一)”),C小加很高兴。但C小加是个爱思考的人,他又想通过这种方法计算一个表达式的值。即先把表达式转换为后缀表达式,再求值。这时又要考虑操作数是小数和多位数的情况。

输入
第一行输入一个整数T,共有T组测试数据(T<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数并且小于1000000。
数据保证除数不会为0。
输出
对于每组测试数据输出结果包括两行,先输出转换后的后缀表达式,再输出计算结果,结果保留两位小数。两组测试数据之间用一个空行隔开。
样例输入
21+2=(19+21)*3-4/5=
样例输出
12+=3.001921+3*45/-=119.20
来源
改编自NYOJ
上传者

xiewuqiang

这道题真的是……唉,一把辛酸泪,没爱了,用的队列,看的别人的代码用的队列,但是一直程序有错误,然后忽略了数组的循环直接将i加了,但是队列得出队列

#include<stdio.h>
#include<string.h>
#include<stack>
#include<queue>
#include<ctype.h>
#include<stdlib.h>
using namespace std;
char str[1010];
stack<char>s;//定义一个栈存操作符
queue<char>q;//定义一个队列存转化后的后缀表达式
int priority(char ch){
	switch(ch){
		case '+':
			case '-':
				return 1;
				break;
		case '*':
			case '/':
				return 2;
				break;
		case '(':return 0;
		default:return -1;
	}
}
int trans(){
	while(!s.empty())
	s.pop();
	while(!q.empty())
	q.pop();
	s.push('=');
	int len=strlen(str);
	for(int i=0;str[i]!='=';i++){
		if(str[i]>='0'&&str[i]<='9'||str[i]=='.'){
			q.push(str[i]);
		}
		else{
			q.push('#');//将连着的多个操作数分隔开
			if(str[i]=='(')
			s.push(str[i]); 
			else if(str[i]==')'){
				while(s.top()!='('){
					q.push(s.top());
					s.pop();
				}
				s.pop();//最后将左括号出栈(输出中不需要括号输出) 
			}
			else{
				while(priority(str[i])<=priority(s.top())){
					q.push(s.top());
					s.pop();
				}
				s.push(str[i]);//等到栈中的元素的优先级小于当前要入栈元素的时候,将元素入栈 
			}
			
		}
	}
	while(s.top()!='='){
		q.push(s.top());
		s.pop();
	} 
	q.push('=');
	return 0;//这里记得return 
}
double Calculate(){//计算(Node:这里的每一步都要出队列) 
	char zs[1010];//转换字符数组,需要存储带小数点的数的字符 
	stack<double>num;//定义一个栈存储操作数
	int k=0;
	int flag=0;
	while(q.front()!='='){
		if(q.front()>='0'&&q.front()<='9'||q.front()=='.'){
			zs[k++]=q.front();
			q.pop();
			flag=1;
		} 
		else{
			if(flag){
				zs[k]='\0';
				num.push(atof(zs));
				k=0;
				flag=0;
			}
			else if(q.front()=='#'){//这个必须得判断,而且需要出队列,否则会循环不完的 
				q.pop();
				continue;
			}
			else if(q.front()!='#'){//为加减乘除 
				double num1=num.top();
				num.pop();
				double num2=num.top();
				num.pop();
				switch(q.front()){
					case '+':
						num.push(num2+num1);
						q.pop();
						break;
					case '-':
						num.push(num2-num1);
						q.pop();
						break;
					case '*':
						num.push(num2*num1);
						q.pop();
						break;
					case '/':
						num.push(num2/num1);
						q.pop();
						break;
				}
			}
		}
	} 
	return num.top();
}
int main(){
	int T;
	char str2[1010];
	scanf("%d",&T);
	while(T--){
		scanf("%s",str);
		trans();
		int t=0;
		while(!q.empty()){
			str2[t++]=q.front();
			q.pop();
			if(str2[t-1]!='#')
			printf("%c",str2[t-1]);
		}
		printf("\n");
		for(int i=0;i<t;i++){
			q.push(str2[i]);
		}
		printf("%.2f\n",Calculate());
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/Dear_Jia/article/details/80241152