表达式求值c++模板(加减乘除小括号)

中缀表达式转后缀表达式

设立一个操作符栈,一个数组存放后缀表达式,从左到右扫描中缀表达式,如果是操作数则加入后缀表达式;如果是操作符则与栈顶元素比较优先级,规则为:(对于当前运算符)左括号一律入栈、右括号一串出栈、优先级高则入栈、小于等于一串出栈。

#include 
#include 
#include 
#include 
#include 

using namespace std;
map pri;

void setPri() {
	pri["#"] = 0;
	pri["+"] = 1;
	pri["-"] = 1;
	pri["*"] = 2;
	pri["/"] = 2;
}

string charToString(char c) {
	string sc;
	sc.push_back(c);
	return sc;
}

vector inToPost(string in) {
	stack op;
	vector post;
	op.push("#");
	string tmp = "";
	for (int i = 0; i < in.size(); i++) {
		if (in[i] >= '0' && in[i] <= '9') {
			tmp += in[i];
		}
		else {
			if (tmp != "") {
				post.push_back(tmp);
				tmp = "";
			}
			if (in[i] == '(') { //左括号一律入栈
				op.push(charToString(in[i]));
			}
			else if (in[i] == ')') { //右括号一串出栈
				while (op.top() != "(") { //括号中间的出栈到后缀表达式
					string t = op.top();
					post.push_back(t);
					op.pop();
				}
				op.pop(); //括号出栈
			}
			else if (pri[charToString(in[i])] > pri[op.top()]) { //优先级高则入栈
				op.push(charToString(in[i]));
			}
			else { //小于等于一串出栈
				while (pri[charToString(in[i])] <= pri[op.top()]) { //比当前运算符大的依次出栈
					string t = op.top();
					post.push_back(t);
					op.pop();
				}
				op.push(charToString(in[i])); //当前运算符入栈
			}
		}
		if (i == in.size() - 1 && tmp != "")
			post.push_back(tmp);
	}
	while (op.top() != "#") {
		string t = op.top();
		post.push_back(t);
		op.pop();
	}
	return post;
}

后缀表达式求值

设立一个操作数栈,从左到右扫描后缀表达式,如果是操作数,就压入栈;如果是操作符,就连续弹出两个操作数(后弹出的是操作数1),计算操作数1 op 操作数2,并将结果压入栈中,直到后缀表达式扫描完毕,这时栈中只会存在一个数,就是最终的答案。

double cal(double num1, string op, double num2) {
	if (op == "+")
		return num1 + num2;
	else if (op == "-")
		return num1 - num2;
	else if (op == "*")
		return num1 * num2;
	else if (op == "/")
		return num1 / num2;
}

double stringToDouble(string str) {
	double tmp = 0;
	for (int i = 0; i < str.size(); i++) {
		tmp = tmp * 10 + str[i] - '0';
	}
	return tmp;
}

double calPost(vector post) {
	stack num;
	for (int i = 0; i < post.size(); i++) {
		if (post[i][0] >= '0' && post[i][0] <= '9')
			num.push(stringToDouble(post[i]));
		else {
			double num2 = num.top();
			num.pop();
			double num1 = num.top();
			num.pop();
			double r = cal(num1, post[i], num2);
			num.push(r);
		}
	}
	return num.top();
}

int main() {
	setPri();
	string str;
	while (cin >> str) {
		vector post = inToPost(str);
		double res = calPost(post);
		cout << res << endl;
	}
}

二合一(中缀表达式求值)

设立一个操作符栈,一个操作数栈,从左到右扫描中缀表达式,如果是操作数则入栈;如果是操作符,则与栈顶操作符比较,有操作符出栈时从操作数栈中弹出两个数,计算后压入操作数栈,最后操作数栈中唯一的一个数就是结果

#include 
#include 
#include 
#include 

using namespace std;

double cal(double a, char op, double b) {
	if (op == '+')
		return a + b;
	else if (op == '-')
		return a - b;
	else if (op == '*')
		return a * b;
	else if (op == '/')
		return a / b;
}

int main() {
	map pri;
	pri['#'] = 0;
	pri['+'] = pri['-'] = 1;
	pri['*'] = pri['/'] = 2;
	string in;
	while (cin >> in) {
		stack op;
		stack num;
		op.push('#');
		for (int i = 0; i < in.size(); i++) {
			if (in[i] >= '0' && in[i] <= '9') {
				double tmp = 0;
				while (i < in.size() && in[i] >= '0' && in[i] <= '9') {
					tmp = tmp * 10 + in[i] - '0';
					i++;
				}
				i--;
				num.push(tmp);
			}
			else {
				if (in[i] == '(') {
					op.push(in[i]);
				}
				else if (in[i] == ')') {
					while (op.top() != '(') {
						char c = op.top();
						op.pop();
						double num2 = num.top();
						num.pop();
						double num1 = num.top();
						num.pop();
						double r = cal(num1, c, num2);
						num.push(r);
					}
					op.pop();
				}
				else if (pri[in[i]] > pri[op.top()]) {
					op.push(in[i]);
				}
				else {
					while (pri[in[i]] <= pri[op.top()]) {
						char c = op.top();
						op.pop();
						double num2 = num.top();
						num.pop();
						double num1 = num.top();
						num.pop();
						double r = cal(num1, c, num2);
						num.push(r);
					}
					op.push(in[i]);
				}
			}
		}
		while (op.top() != '#') {
			char c = op.top();
			op.pop();
			double num2 = num.top();
			num.pop();
			double num1 = num.top();
			num.pop();
			double r = cal(num1, c, num2);
			num.push(r);
		}
		cout << num.top() << endl;
	}
}

参考

《算法笔记》(胡凡)

你可能感兴趣的:(表达式求值c++模板(加减乘除小括号))