逆波兰表达式实现四则运算(C++版)

复习算法时写的, 代码能运行没问题:

//逆波兰表达式实现四则运算
#include 
#include 
#include 
using namespace std;

bool is_operator(string op)//判断是否运算符
{
	return (op == "+" || op == "-"
            || op == "*" || op == "/" 
            || op == "(" || op == ")");
}

int get_priority(string op)//比较运算符号的优先级
{
	if (op == "+" || op == "-")
		return 1;
	if (op == "*" || op == "/")
		return 2;
	else return 0;
}

string get_result(string val1, string val2, string op) 
{
	double v1 = stod(val1);
	double v2 = stod(val2);// 转化为double型
	double result;
	if (op == "+")
		result = v1 + v2;
	if (op == "-")
		result = v2 - v1;
	if (op == "*")
		result = v1 * v2;
	if (op == "/")
		result = v2 / v1;
	
	ostringstream os;
	os << result;
	return os.str();	//将double型的数据送入输出流并转化为string型
}

stack transform(string input)	//逆波兰表达式转换
{
	stack converted;	//定义一个数字栈,用于存放转换成的逆波兰表达式
	stack op;	//定义一个运算符栈,字符型
	size_t i = 0; //依次读取输入的字符串字符
	string digit_node = ""; //用于连接一个完整的数字

	while(i < input.length()) {
		char c = input[i];///获取当前字符
		string read_char = "";///
		read_char += c;///这三行怪怪的,要这么写能通过,不能将这行和上一行写成:string read_char = string(&c); 不知道为什么
		
		if (is_operator(read_char)) {	//判断是否运算符
			if (digit_node != "") {	//如果当前读取到运算符,则表示之前数字的读取结束
					converted.push(digit_node);	//将之前读取到的数字字符串存入数字栈
					digit_node = "";	//将数字字符串置空
			}
				
			if (op.empty()) {	//当前读取到的是运算符栈的第一个操作符,则直接将操作符进栈
				op.push(read_char);
			}
			else {
				
				if (read_char == "(")//读取到左括号, 直接进栈
					op.push(read_char);
				else if (read_char == ")") { //读取到右括号,则将上一个左括号之前的运算符全部出栈
					while (op.top() != "(") {
						converted.push(op.top());	//
						op.pop();
					}
					op.pop(); // 将上一个左括号出栈
				}
				else if (get_priority(read_char) >= get_priority(op.top()))//比较运算符级别
					op.push(read_char); //若高于等于上一个运算符则直接入运算符栈
				else {//否则弹出两个数字和一个符号,将运算结果再次压入数字栈
					converted.push(op.top());
					op.pop();
					op.push(read_char);
				}
			}
		} else
			digit_node += read_char;//将每次读取的单个数字字符相加
		i++;
	}
	
	if (digit_node != "")
		converted.push(digit_node); //入栈最后一个数字

	while (!op.empty()) {//将剩余的运算符栈所有元素压入栈
		converted.push(op.top());
		op.pop();
	}
	
	stack stk;
	while (!converted.empty()){	//颠倒逆波兰表达式的入栈顺序送入另一个栈
		stk.push(converted.top());
		converted.pop();
	}
	return stk;
}

double rpn(string input) 
{
	stack stk1 = transform(input);
	stack rs;
	while (!stk1.empty()) {
		if (is_operator(stk1.top())) {//每遇到一个运算符就弹出两个数字与其进行运算,然后再将结果入栈
			string val1 = rs.top();
			rs.pop();
			string val2 = rs.top();
			rs.pop();
			string op = stk1.top();
			stk1.pop();
			rs.push(get_result(val1, val2, op));
		} else {
			rs.push(stk1.top());
			stk1.pop();
		}
	}
	return stod(rs.top());
}

int main(int argc, char** argv)
{
	string input;
	while ((cout << "请输入运算公式:") && (cin >> input)) {
		cout << "结果为:" << rpn(input) << endl;
	}
	return 0;
}


你可能感兴趣的:(C++笔记)