C++ 后缀表达式(逆波兰表达式),并求值(也可求小数、负数与大于10的数)

后缀表达式(逆波兰表达式),并求值

这是一个栈的简单应用。
规则:从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;
若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于找顶符号(乘除优先加减)则栈顶元素依次出找并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。

支持()、+、-、*、/、%、整数、小数、负数


#include <stdexcept>
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <regex>
#include <cmath>

using namespace std;

//拆分字符
vector<string> Split() {
	vector<string> temp_VecStr;
	regex reg_dig("[[:digit:].]");
	string temp_str, temp_str1, temp_str2, temp_str3;

	cout << "请输入表达式:" << endl;
	cin >> temp_str;

	for (auto i = temp_str.begin(); i != temp_str.end(); ++i) {
		temp_str2 = *i;

		if (regex_search(temp_str2, reg_dig)) {
			temp_str1 += temp_str2;

			auto p = i;

			if (++p == temp_str.end()) {
				temp_VecStr.push_back(temp_str1);
				temp_str1.clear();
			}
			--p;

			if (++p != temp_str.end()) {
				--p;
				temp_str2 = *(++p);

				if (!regex_search(temp_str2, reg_dig)) {
					temp_VecStr.push_back(temp_str1);
					temp_str1.clear();
				}
			}
		}
		else {
			if (temp_str2 == "+" || temp_str2 == "-" || temp_str2 == "*" || temp_str2 == "/" || temp_str2 == "(" || temp_str2 == "%") {
				temp_VecStr.push_back(temp_str2);

				auto p = i;
				if (++p != temp_str.end()) {
					--p;

					temp_str3 = *(++p);
					if (temp_str3 == "-") {
						temp_str1 += temp_str3;

						if (++p != temp_str.end()) {
							auto p1 = p;
							temp_str3 = *p1;
							for (; regex_search(temp_str3, reg_dig) && p1 != temp_str.end(); ++p1, ++i) {
								temp_str3 = *p1;
								if (regex_search(temp_str3, reg_dig)) {
									temp_str1 += temp_str3;
								}
							}
							temp_VecStr.push_back(temp_str1);
							temp_str1.clear();
							if (regex_search(temp_str3, reg_dig)) {
								++i;
							}
						}
					}
				}
			}
			else {
				temp_VecStr.push_back(temp_str2);
			}
		}
	}

	return temp_VecStr;
}

//转换为后缀表达式
stack<string> Postfix_Expression(vector<string> temp_VecStr) {
	stack<string> temp_StackSymbol, temp_StackExp, temp_Stack1, temp_Stack2;
	regex reg_dig("[[:digit:].]+");
	string temp_str;

	for (auto &i : temp_VecStr) {
		temp_str = i;

		if (regex_search(temp_str, reg_dig)) {
			temp_StackExp.push(temp_str);
		}

		if (temp_str == "(") {
			temp_StackSymbol.push(temp_str);
		}

		if (temp_str == ")") {
			while (temp_StackSymbol.top() != "(") {
				temp_StackExp.push(temp_StackSymbol.top());
				temp_StackSymbol.pop();
			}
			temp_StackSymbol.pop();
		}

		if (temp_str == "+" || temp_str == "-") {
			if (!temp_StackSymbol.empty()) {
				if (temp_StackSymbol.top() == "+" || temp_StackSymbol.top() == "-" || temp_StackSymbol.top() == "*" || temp_StackSymbol.top() == "/" || temp_StackSymbol.top() == "%") {
					while (!temp_StackSymbol.empty() && temp_StackSymbol.top() != "(") {
						temp_StackExp.push(temp_StackSymbol.top());
						temp_StackSymbol.pop();
					}
					temp_StackSymbol.push(temp_str);
				}
				else {
					temp_StackSymbol.push(temp_str);
				}
			}
			else {
				temp_StackSymbol.push(temp_str);
			}
		}

		if (temp_str == "%") {
			if (!temp_StackSymbol.empty()) {
				if (temp_StackSymbol.top() == "*" || temp_StackSymbol.top() == "/" || temp_StackSymbol.top() == "%") {
					while (!temp_StackSymbol.empty() && temp_StackSymbol.top() != "(" && temp_StackSymbol.top() != "+" && temp_StackSymbol.top() != "-") {
						temp_StackExp.push(temp_StackSymbol.top());
						temp_StackSymbol.pop();
					}
					temp_StackSymbol.push(temp_str);
				}
				else {
					temp_StackSymbol.push(temp_str);
				}
			}
			else {
				temp_StackSymbol.push(temp_str);
			}
		}

		if (temp_str == "*" || temp_str == "/") {
			if (!temp_StackSymbol.empty()) {
				if (temp_StackSymbol.top() == "*" || temp_StackSymbol.top() == "/") {
					while (!temp_StackSymbol.empty() && temp_StackSymbol.top() != "(" && temp_StackSymbol.top() != "+" && temp_StackSymbol.top() != "-") {
						temp_StackExp.push(temp_StackSymbol.top());
						temp_StackSymbol.pop();
					}
					temp_StackSymbol.push(temp_str);
				}
				else {
					temp_StackSymbol.push(temp_str);
				}
			}
			else {
				temp_StackSymbol.push(temp_str);
			}
		}
	}

	while (!temp_StackSymbol.empty()) {
		temp_StackExp.push(temp_StackSymbol.top());
		temp_StackSymbol.pop();
	}

	while (!temp_StackExp.empty()) {
		temp_Stack1.push(temp_StackExp.top());
		temp_Stack2.push(temp_StackExp.top());
		temp_StackExp.pop();
	}

	cout << endl << "其后缀表达式为:" << endl << endl;
	while (!temp_Stack2.empty()) {
		cout << temp_Stack2.top() << " ";
		temp_Stack2.pop();
	}
	cout << endl << endl;

	return temp_Stack1;
}

//求值
void Evaluation(stack<string> temp_StackExp) {
	auto temp_num1 = 0.0, temp_num2 = 0.0;
	regex reg_dig("[[:digit:].]+");
	stack<double> temp_StackNum;
	string temp_str;

	try {
		while (!temp_StackExp.empty()) {
			temp_str = temp_StackExp.top();

			if (regex_search(temp_str, reg_dig)) {
				temp_StackNum.push(stod(temp_str));
				temp_StackExp.pop();
			}

			if (temp_str == "+") {
				if (!temp_StackNum.empty()) {
					temp_num1 = temp_StackNum.top();
					temp_StackNum.pop();
					temp_num2 = temp_StackNum.top();
					temp_StackNum.pop();
					temp_StackNum.push(temp_num1 + temp_num2);
					temp_StackExp.pop();
				}
				else {
					throw runtime_error("表达式输入错误,请重新输入!");
				}
			}

			if (temp_str == "-") {
				if (!temp_StackNum.empty()) {
					temp_num1 = temp_StackNum.top();
					temp_StackNum.pop();
					temp_num2 = temp_StackNum.top();
					temp_StackNum.pop();
					temp_StackNum.push(temp_num2 - temp_num1);
					temp_StackExp.pop();
				}
				else {
					throw runtime_error("表达式输入错误,请重新输入!");
				}
			}

			if (temp_str == "%") {
				if (!temp_StackNum.empty()) {
					temp_num1 = temp_StackNum.top();
					temp_StackNum.pop();
					temp_num2 = temp_StackNum.top();
					temp_StackNum.pop();
					temp_StackNum.push(fmod(temp_num2, temp_num1));
					temp_StackExp.pop();
				}
				else {
					throw runtime_error("表达式输入错误,请重新输入!");
				}
			}

			if (temp_str == "*") {
				if (!temp_StackNum.empty()) {
					temp_num1 = temp_StackNum.top();
					temp_StackNum.pop();
					temp_num2 = temp_StackNum.top();
					temp_StackNum.pop();
					temp_StackNum.push(temp_num1 * temp_num2);
					temp_StackExp.pop();
				}
				else {
					throw runtime_error("表达式输入错误,请重新输入!");
				}
			}

			if (temp_str == "/") {
				if (!temp_StackNum.empty()) {
					temp_num1 = temp_StackNum.top();
					temp_StackNum.pop();
					temp_num2 = temp_StackNum.top();
					temp_StackNum.pop();
					temp_StackNum.push(temp_num2 / temp_num1);
					temp_StackExp.pop();
				}
				else {
					throw runtime_error("表达式输入错误,请重新输入!");
				}
			}
		}
	}

	catch (runtime_error &err) {
		cout << err.what() << endl;
		return Evaluation(Postfix_Expression(Split()));
	}

	cout << "表达式的值为: " << temp_StackNum.top() << endl << endl;
}

int main() {
	while (1) {
		Evaluation(Postfix_Expression(Split()));
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值