C++实现四则运算表达式的计算

输入为一个整数四则运算表达式,可以有括号。

程序实现:

  • 判断括号是否合法
  • 将表达式转换为后缀表达式
  • 计算出表达式的结果

(这里使用自己实现的栈类辅助操作)

代码如下:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

/*---------------------------全局变量---------------------------------*/

int PRIORITY_TAB[6][6] = {0,0,0,0,1,-1,
						  0,0,0,0,1,-1,
						  1,1,0,0,1,-1,
						  1,1,0,0,1,-1,
						  1,1,1,1,1,-1,
						  0,0,0,0,0,-1,};
string OPERATORS("+-*/()");

/*-------------------------函数和类声明-------------------------------*/

template <class T>
class Stack;
bool check_balance(const string& expr);
vector<string> infix_to_postfix(const string& infix);//中缀转后缀
int check_priority(char input, char top);//检查优先级
int calc_unit(int opr1, int opr2, char op);//计算两个数据的运算结果
int infix_calc(const string& infix);//计算中缀表达式的结果
int pop_two_operands_and_calc(Stack<int>& opr, Stack<char>& ope);//

/*---------------------------类的实现---------------------------------*/

template <class T>
class Stack
{
public:
	Stack() {};
	void push_back(const T& t);
	T pop_back();
	int get_len() { return (int)stack.size(); }
	T back() { return stack.back(); }
private:
	vector<T> stack;
};

template <class T>
void Stack<T>::push_back(const T& t)
{
	stack.push_back(t);
}

template <class T>
T Stack<T>::pop_back()
{
	T temp = stack.back();
	stack.pop_back();
	return temp;
}

/*----------------------------主函数----------------------------------*/
int main()
{
	string expression;
	cout << "Please input an expression: " << endl;
	cin >> expression;
	cout << endl;
	cout << "Checking balance..." << endl;
	while (!check_balance(expression))
	{
		cout << "Symbols are not balance! Please try again!" << endl;
		cin >> expression;
	}
	cout << endl;
	cout << "Its postfix is: " << endl;	
	vector<string> postfix = infix_to_postfix(expression);
	for (auto a = postfix.begin(); a != postfix.end(); a++)
		cout << *a << "  ";
	cout << endl;
	cout << endl;
	cout << "The result of this infix expression is: " << endl;
	int res = infix_calc(expression);
	cout << res << endl;
	cout << endl;

	system("pause");
	return 0;
}

/*---------------------------函数实现---------------------------------*/

int check_priority(char input, char top)
{
	return PRIORITY_TAB[OPERATORS.find(input)][OPERATORS.find(top)];
}

bool check_balance(const string& expr)
{
	Stack<char> symbols;
	for (int i = 0; i < expr.length(); i++)
	{
		if (expr[i] == '(')
			symbols.push_back(expr[i]);
		else if (expr[i] == ')')
		{
			if (symbols.get_len() && symbols.back() == '(')
				symbols.pop_back();
			else
				return false;
		}
	}
	if (symbols.get_len())
		return false;
	else
		return true;
}

vector<string> infix_to_postfix(const string& infix)
{
	vector<string> postfix;
	Stack<char> operators;

	for (int i = 0; i < infix.length(); )
	{
		//数字
		string digital("");
		while (infix[i] >= 0x30 && infix[i] <= 0x39 && i < infix.length())
		{
			digital += infix[i];
			i++;
		}
		if (digital.length())
		{
			postfix.push_back(digital);
			continue;
		}
			
		//运算符
		if (OPERATORS.find(infix[i]) != OPERATORS.npos)//判断符号是否合法
		{
			if (operators.get_len() == 0 || 
				check_priority(infix[i], operators.back()) == 1) //如果当前符号栈为空或栈顶优先级低
			{
				operators.push_back(infix[i]);
			}
			else if (OPERATORS.find(infix[i]) == 5)//遇到右括号
			{
				while (operators.back() != '(')
				{
					string temp(1, operators.pop_back());
					postfix.push_back(temp);
				}
				operators.pop_back();//最后把左括号弹出
			}
			else if (check_priority(infix[i], operators.back()) == 0)//栈顶优先级高且不是右括号
			{
				while (operators.get_len() && operators.back() != '(') //如果有左括号则只弹出左括号以上的部分
				{
					string temp(1, operators.pop_back());
					postfix.push_back(temp);
				}
				operators.push_back(infix[i]);
			}
			i++;
		}
	}
	while (operators.get_len())//最后如果栈非空,则弹出所有运算符
	{
		string temp(1, operators.pop_back());
		postfix.push_back(temp);
	}
	return postfix;
}

int calc_unit(int opr1, int opr2, char op)
{
	switch (op)
	{
	case '+': return opr1 + opr2;
	case '-': return opr1 - opr2;
	case '*': return opr1 * opr2;
	case '/': return opr1 / opr2;

	default:
		return 0;
	}
}

int infix_calc(const string& infix)
{
	Stack<char> operators;
	Stack<int> operand;
	for (int i = 0; i < infix.length(); )
	{
		//数字
		string digital_str("");
		while (infix[i] >= 0x30 && infix[i] <= 0x39 && i < infix.length())
		{
			digital_str += infix[i];
			i++;
		}
		if (digital_str.length())
		{
			int digital = atoi(digital_str.c_str());
			operand.push_back(digital); //数字压进数字栈
			continue;
		}

		//运算符
		if (OPERATORS.find(infix[i]) != OPERATORS.npos)//判断符号是否合法
		{
			if (operators.get_len() == 0 ||
				check_priority(infix[i], operators.back()) == 1) 
			{
				operators.push_back(infix[i]);
			}
			else if (OPERATORS.find(infix[i]) == 5)//遇到右括号
			{
				while (operators.back() != '(')
				{
					int res = pop_two_operands_and_calc(operand, operators);
					operand.push_back(res);//计算结果压栈
				}
				operators.pop_back();//最后把左括号弹出
			}
			else if (check_priority(infix[i], operators.back()) == 0)
			{
				while (operators.get_len() && operators.back() != '(') 
				{
					int res = pop_two_operands_and_calc(operand, operators);
					operand.push_back(res);//计算结果压栈
				}
				operators.push_back(infix[i]);
			}
			i++;
		}
	}
	while (operators.get_len())//最后如果栈非空,则弹出所有
	{
		int res = pop_two_operands_and_calc(operand, operators);
		operand.push_back(res);//计算结果压栈;
	}
	return operand.pop_back();
}

int pop_two_operands_and_calc(Stack<int>& opr, Stack<char>& ope)
{
	char op = ope.pop_back();
	int opr2 = opr.pop_back();//弹出两个数并计算
	int opr1 = opr.pop_back();
	int res = calc_unit(opr1, opr2, op);
	return res;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值