用后缀表达式求解算术表达式

118.算术表达式求值 
C时间限制:3000 毫秒 |  C内存限制:3000 Kb
题目内容:
 输入一个由数字、+,-,*,/ 组成的算术表达式,求其值。
输入描述
一个表达式,其中每个运算数为正整数
输出描述
计算结果,保留2位小数
输入样例
1+12*3-4/2
输出样例
35.00

解题思路:
1转换为后缀表达式 
2利用后缀表达式求值 
这里栈就派上用场了,从左到右一个个遍历表达式,遇到操作数就入栈,
遇到操作符就依次取出栈顶的两个操作数进行计算,并把计算结果入栈,
供后面计算,直到栈为空,说明表达式计算完毕,否则说明表达式有问题。

求后缀表达式样例 
2+3*(7-4)
2 3 7 4 - * +

12+23*(37-14)
12 23 37 14 - * + 

#include
#include
#include
using namespace std;
const int len=10000;
char ifx[len+1];//中缀 
char sfx[2*len+1];//后缀 
bool IsDig(char a){//判断是否为数字 
	if('0'<=a&&a<='9')return true;
	else return false;
} 
bool IsOperator(char a){//判断是否为运算符 
	if(a=='+'||a=='-'||a=='*'||a=='/')return true;
	else return false;
}
bool Yxj(char a,char b){//判断优先级 
	int x,y;
	switch(a){
		case '*':
		case '/':x=2;break;
		case '+':
		case '-':x=1;break;
	}
	switch(b){
		case '*':
		case '/':y=2;break;
		case '+':
		case '-':y=1;break;
	}
	if(x>=y)return true;
	else return false;
}
//中缀转后缀
void infixToSuffix(){
	stack optr;//运算符符
	while(optr.empty()==false) optr.pop();
	int k=0;
	sfx[k]='\0';
	for(int i=0;ifx[i];i++){ 
		if(IsDig(ifx[i])){//遇到数字直接输出到sfx 
			sfx[k++]=ifx[i];
			if(!IsDig(ifx[i+1]))
				sfx[k++]=' ';//当后面一个不是数字时才输入空格		
		}else if(ifx[i]=='('){//遇到前括号直接入栈 
			optr.push(ifx[i]);
		}else if(ifx[i]==')'){//遇到后括号 ,出栈,直到遇到前括号 
			while(optr.top()!='('){
				sfx[k++]=optr.top();
				sfx[k++]=' ';
				optr.pop();
			}optr.pop();
		}else if(IsOperator(ifx[i])){//遇到运算符 
			if(optr.empty())//栈为空时直接入栈 
				optr.push(ifx[i]);
			else{ 
				 while(Yxj(optr.top(),ifx[i])){ //当栈为空时,访问top()会出错 
				 	sfx[k++]=optr.top();
				 	sfx[k++]=' ';
					optr.pop();
					if(optr.empty())//加了这一行,问题解决了 
						break;	
				 }
				 optr.push(ifx[i]);	
			} 
		}	
	}
	while(!optr.empty()){
		sfx[k++]=optr.top();
		sfx[k++]=' ';
		optr.pop();	
	}
	sfx[k-1]='\0';	
}
//计算一次 
double calOnce(double a,char optr,double b){
	switch(optr){
		case '+':return a+b;
		case '-':return a-b;
		case '*':return a*b;
		case '/':return a/b;
	}
}
//用后缀表达式计算结果 
//12 23 37 14 - * +
double getAnswer(){
	infixToSuffix();
	//puts(sfx);
	stack dig;//操作数栈
	while(dig.empty()==false)dig.pop();
	double x=0;
	double a,b,ans=0;
	for(int i=0;sfx[i];i++){
		if(sfx[i]==' ') continue;
		else if(IsDig(sfx[i])){
			if(IsDig(sfx[i+1]))
				x=x*10+sfx[i]-'0';
			else{
				x=x*10+sfx[i]-'0';
				dig.push(x);
				x=0; 
			}
		}else{//遇到操作符 
			b=dig.top();dig.pop();
			a=dig.top();dig.pop();//先入栈的计算时应该在前面 
			ans=calOnce(a,sfx[i],b);
			//printf("%.2lf%c%.2lf=%.2lf\n",a,sfx[i],b);
			dig.push(ans); 
		}
	}
	return ans;	
}
int main(){
while(~scanf("%s",ifx)){
	printf("%.2lf\n",getAnswer());
}	
	return 0;
}

 

你可能感兴趣的:(algorithm)