【Openjudge】中缀表达式的值

队列和栈来回倒腾。

思路是比较典型的思路,现转成逆波兰表达式(运用栈),然后输入到队列,然后计算值(运用栈)。

中缀表达式转化逆波兰(后缀表达式)思路是这样的。

首先,逆波兰表达式的数字顺序是和中缀一样的。于是数字方面我们只需要碰到一个输入到队列一个即可。关键在于,运算符号怎么处理。

容易注意到,我们所需要做的就是调整中缀表达式的运算符的出现顺序,并输出到逆波兰中,使之与中缀表达式的计算顺序一致。如何做到这一点呢?需要运用栈。

首先明白这么几点:

1,在没有括号的情况下,如果两个相邻的操作符是相同的,先出现的一定需要被先计算。eg:a+b+c,第一个加号一定先于第二个运算,但是注意,我们并不知道下一个运算是否是第二个加号。eg:a+b+c*d,显然,第一个+号运算之后,是*号运算,然后才是第二个+号运算。

2,在没有括号的情况下,如果第一个操作符的优先级高于第二个,则,第一个操作符一定被先计算,同样,我们不知道下一个运算是不是第二个操作符。

3,在没有括号的情况下,如果第二个操作符的优先级高于第一个,则,这两个操作符的顺序需要变换(需要运用到栈的地方,后进先出)。

4,右括号,先进行括号内的运算。

这四条明白了,意味着我们知道什么时候需要运用到栈调整运算符的出现顺序。

代码最难的地方就是这个地方了,计算逆波兰表达式,比较简单,碰到数字压栈,碰到符号,弹出栈顶的两个元素,计算结果,将结果压栈,知道全部读入完毕,栈顶即结果。

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

bool opcmp(char op1, char op2){
	if (op1 == '+' || op1 == '-'){ 
		if (op2 == '*' || op2 == '/'){
			return false;
		}
	}
	return true;
}

int main()
{
	stack ist;
	stack cst;
	queue cq;
	char a[700] = {};
	int n;
	char c;
	cin >> n;
	while (n --){
		cin >> a;
		{
			for (int i = 0; a[i] != 0; i ++){
				c = a[i];
				if (c >= '0' && c <= '9'){
					string t;
					while(a[i] >= '0' && a[i] <= '9'){
						t.push_back(a[i]);
						i++;
					}
					i --;
					cq.push(t);
				}
				else{
					if (c == '('){
						cst.push(c);
					}
					else if (c == ')'){
						while (cst.top() != '('){
							cq.push(string(1,cst.top()));
							cst.pop();
						}
						cst.pop();
					}
					else if (cst.empty()){
						cst.push(c);
					}
					else if (opcmp(cst.top(), c)){
						while (!cst.empty() && cst.top() != '(' && opcmp(cst.top(), c)){
							cq.push(string(1,cst.top()));
							cst.pop();
						}
						cst.push(c);
					}
					else{
						cst.push(c);
					}
				}
			}
		}
		while (!cst.empty()){
			cq.push(string(1,cst.top()));
			cst.pop();
		}
		int x, y;
		while (!cq.empty()){
			string t = cq.front();
			if (t[0] >= '0' && t[0] <= '9'){
				ist.push(atoi(t.c_str()));
			}
			else{
				y = ist.top();
				ist.pop();
				x = ist.top();
				ist.pop();
				switch(t[0]){
					case '+':
						ist.push(x + y);
						break;
					case '-':
						ist.push(x - y);
						break;
					case '*':
						ist.push(x * y);
						break;
					case '/':
						ist.push(x / y);
						break;
				}
			}
			cq.pop();
		}
		cout << ist.top();
		ist.pop();
		cout << endl;
	}
}

你可能感兴趣的:(Openjudge)