栈的应用——四则运算表达式求值

#include
#include
#include
#include
#include
#include
using namespace std;

struct node{
	double num;	//操作数 
	char op;	//操作符 
	bool flag;	//true表示是操作数,false表示是操作符 
};

string str;		//读入的字符串 
stack s; 	//在Change()函数里存的是操作符,在Cal()函数里存的是操作数 
queue q;	//后缀表达式序列
map op;	//符号优先级 

//将中缀表达式转换为后缀表达式
void Change(){
	double num;	//记录操作数 
	node temp;	//要记录的节点 
	for(int i=0;i='0'&&str[i]<='9'){	//如果是数字 
			temp.flag=true;	//标记是数字 
			temp.num=str[i++]-'0';	//记录这个操作数的第一个数位 
			//如果数字后面还是数字,就把连续的数字放在一起 
			while(i='0'&&str[i]<='9'){
				temp.num=temp.num*10+(str[i++]-'0');
			}
			q.push(temp);	//将这个操作数压入后缀表达式的队列 
		}else{	//如果是操作符 
			temp.flag=false;	//标记是操作符 
			//只要操作符栈的栈顶元素比该操作符优先级高
			//就把操作符栈栈顶元素弹出到后缀表达式的队列中 
			while(!s.empty()&&op[str[i]]<=op[s.top().op]){
				q.push(s.top());
				s.pop();
			}
			temp.op=str[i];
			s.push(temp);	//把该操作符压入操作符栈中 
			i++;
		} 
	}
	//如果操作符栈中还有操作符,就把它弹出到后缀表达式队列中 
	while(!s.empty()){
		q.push(s.top());
		s.pop();
	} 
} 

//计算后缀表达式
double Cal(){
	double temp1,temp2;
	node cur,temp;
	while(!q.empty()){	//只要后缀表达式队列非空 
		cur=q.front();	//cur记录队首元素 
		q.pop();
		//如果是操作数,直接压入栈 
		if(cur.flag==true) s.push(cur);
		else{	//如果是操作符 
			temp2=s.top().num;	//弹出第二操作数 
			s.pop();
			temp1=s.top().num;	//弹出第一操作数 
			s.pop();
			temp.flag=true;		//记录临时操作数 
			if(cur.op=='+') temp.num=temp1+temp2;	//加法 
			else if(cur.op=='-') temp.num=temp1-temp2;	//减法 
			else if(cur.op=='*') temp.num=temp1*temp2;	//乘法 
			else temp.num=temp1/temp2;	//除法 
			s.push(temp); 	//把该操作数压入栈 
		}
	}
	return s.top().num;	//栈顶元素就是后缀表达式的值 
} 

int main(){
	op['+']=op['-']=1;
	op['*']=op['/']=2;
	while(getline(cin,str),str!="0"){	//从标准输入读一行数据 
		for(string::iterator it=str.end();it!=str.begin();it--){
			if(*it==' ') str.erase(it);	//从后往前去除空格 
		}
		while(!s.empty()) s.pop();	//初始化栈 
		Change();	//将中缀表达式转换为后缀表达式
		printf("%.2f\n",Cal());	//计算后缀表达式 
	}
	return 0;
}

 

你可能感兴趣的:(算法学习)