利用两个栈求解算数表达式的源代码

说明:

1、只包含了小括号(),和+、-、*、/二元操作符的四则运算

2、求它更通用的求解方法可以参考递归求解、通过表达式树求解的方法

 

#include <cctype>
#include <map>
#include <stack>
#include <string>
#include <iostream>

using namespace std;

//弹出操作符栈的一个操作符,弹出操作数栈的一个操作数,计算结果
void Compute(stack<char> &operators, stack<double> &operands)
{
	double op2 = operands.top();
	operands.pop();
	double op1 = operands.top();
	operands.pop();
	char optr = operators.top();
	double result;
	switch(optr)
	{
	case '+':
		result = op1 + op2;
	case '-':
		result = op1 - op2;
	case '*':
		result = op1 * op2;
	case '/':
		result = op1 / op2;
	}
	operands.push(result);
	operators.pop();
}

//通过操作符栈和操作数栈求解表达式,表达式正确返回true,结果存在result里,错误返回false
bool ComputeExpr(const string &expr, map<char,int> &priority_tbl, double &result)
{
	stack<double> operands;//操作数栈
	stack<char> operators;//操作符栈

	string inner_expr(expr + '$');//加个哨兵
	operators.push('#');//哨兵

	for(int i = 0; i < inner_expr.length(); ++i)
	{
		char ch = inner_expr[i];
		if(isdigit(ch))//操作数直接入操作数栈
			operands.push(ch - 0x30);
		else//操作符
		{
			switch(ch)
			{
			case '(':
				operators.push(ch);
				break;
			case ')': //求解当前最内部的括号表达式
				while(operators.top() != '(')
				{
					if(operators.top() == '#' || operands.size() < 2)
						return false;
					Compute(operators, operands);
				}
				operators.pop();
				break;
			case '$': //此时,正确表达式已经不存在括号了,计算
				while(operators.top() != '#')
				{
					if(operands.size() < 2)
						return false;
					Compute(operators, operands);
				}
				if(operands.size() == 1)
				{
					result = operands.top();
					return true;
				}
				return false;
			default: //一般的二元操作符求解
				while(priority_tbl[ch] <= priority_tbl[operators.top()])
				{
					if(operands.size() < 2)
						return false;
					Compute(operators, operands);
				}
				operators.push(ch);
			}
		}
	}
}

int main(int argc, char *argv[])
{
	const string expr_str("((5+6)*7/(2-9)*9)+5");

	//优先级表,数字越大,优先级越高
	map<char, int> priority_tbl;
	priority_tbl.insert(make_pair('+',2));
	priority_tbl.insert(make_pair('-',2));
	priority_tbl.insert(make_pair('*',3));
	priority_tbl.insert(make_pair('/',3));
	priority_tbl.insert(make_pair('(',1));
	priority_tbl.insert(make_pair('#',0));

	double result;

	bool ret = ComputeExpr(expr_str, priority_tbl, result);

	if(ret)
	{
		cout << expr_str << " = " << result << endl;
	}
	else
	{
		cout << "表达式错误!" << endl;
	}

	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值