输入为一个整数四则运算表达式,可以有括号。
程序实现:
- 判断括号是否合法
- 将表达式转换为后缀表达式
- 计算出表达式的结果
(这里使用自己实现的栈类辅助操作)
代码如下:
#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;
}