四则表达式计算

计算四则表达式

如 1-10(10-10)-12,输出对应的结果

思路

这是一条比较常规的栈的题目,将中缀表达式转换为后缀,在编码过程中,有几个点犯了错误
1、中缀转后缀时,运算符要和stack栈顶的优先级判断,如果优先级小于或等于栈顶,要把栈顶出栈
2、负号的判断,只有前面是括号或者是运算符,才可能是括号,尽可能采用正向判断,避免错误,我最开始判断是前一个不是数字,前一个不是数字,也有可能是右括号或运算符

代码

#include <iostream>
#include <cstdio>
#include <stack>
#include <vector>
#include <string>

using namespace std;

#define is_digit(x) (x>='0' && x<='9')
#define is_right(x) (x==')' || x==']' || x== '}')
#define is_left(x) (x=='(' || x=='[' || x== '{')

struct Item {
	int type;
	int val;
	char op;
};

bool is_oper_high(char a, char b)
{
	int pri_a;
	int pri_b;

	if(a == '+' || a == '-') {
		pri_a = 0;
	} else {
		pri_a = 1;
	}

	if(b == '+' || b == '-') {
		pri_b = 0;
	} else {
		pri_b = 1;
	}

	return pri_a >= pri_b;
}

int do_op(int a, int b, char c)
{
	if(c == '+') {
		return a+b;
	} else if(c == '-') {
		return a-b;
	} else if(c == '*') {
		return a*b;
	} else {
		return a/b;
	}
}

int get_width(int val)
{
	int s = 0;

	if(val == 0) {
		return 1;
	} else if(val < 0) {
		val = 0 - val;
	}

	while(val != 0) {
		val /= 10;
		s++;
	}

	return s;
}

int calc(string &mid_prefix)
{
	int sum = 0;
	char c = 0;
	struct Item item;
	int neg_flag = 0;
	int pos = 0;
	int val;

	vector <struct Item> post_prefix;
	stack <char> oper_stack;

	while(pos < mid_prefix.size()) {
		c = mid_prefix[pos];

		/*判断负数*/
		if(c == '-' && is_left(mid_prefix[pos-1])) {
			sscanf(mid_prefix.substr(pos).c_str(), "%d", &val);
			item.type = 0;
			item.val = val;
			post_prefix.push_back(item);

			pos += get_width(val) + 1;
		} else {
			if(is_digit(c)) {
				sscanf(mid_prefix.substr(pos).c_str(), "%d", &val);
				item.type = 0;
				item.val = val;
				post_prefix.push_back(item);

				pos += get_width(val);
			} else {
				if(!is_right(c)) {
					if(is_left(c)) {
						oper_stack.push('(');
					} else {
						/*判断当前字符和栈顶的优先级,弹出优先级高的元素,或者到(截止*/
						while(!oper_stack.empty() && oper_stack.top() != '(' && is_oper_high(oper_stack.top(), c)) {
							item.type = 1;
							item.op = oper_stack.top();
							post_prefix.push_back(item);
							oper_stack.pop();
						}

						oper_stack.push(c);
					}
				} else {
					/*出栈*/
					while(oper_stack.top() != '(') {
						item.type = 1;
						item.op = oper_stack.top();
						post_prefix.push_back(item);

						oper_stack.pop();
					}
					oper_stack.pop();
				}

				pos++;
			}
		}
	}

	/*操作符出栈*/
	while(!oper_stack.empty()) {
		item.type = 1;
		item.op = oper_stack.top();
		post_prefix.push_back(item);

		oper_stack.pop();
	}

	/*
	for(int i = 0; i<post_prefix.size(); i++) {
		if(post_prefix[i].type == 0) {
			cout << post_prefix[i].val << " ";
		} else {
			cout << post_prefix[i].op << " ";
		}
	}
	cout << endl;
	*/

	/*后缀表达式计算*/
	stack <int> num_stack;
	for(int i=0; i<post_prefix.size(); i++) {
		if(post_prefix[i].type == 0) {
			num_stack.push(post_prefix[i].val);
		} else {
			int a = num_stack.top();
			num_stack.pop();
			int b = num_stack.top();
			num_stack.pop();

			/*do op*/
			sum = do_op(b, a, post_prefix[i].op);
			num_stack.push(sum);
		}
	}

	return sum;
}

int main(void)
{
	string mid_prefix;

	while(cin >> mid_prefix) {
		cout << calc(mid_prefix) << endl;
	}

	return 0;
}
posted @ 2020-02-16 11:48  joechow  阅读(154)  评论(0)    收藏  举报