下午花了一个多小时写了一个栈计算器,也算是对栈的应用的复习了,还记得大一的时候也写过这玩意,可是那时候我好像花的时间是两个下午。
在讲解这个栈计算器的大体思路前,我先讲解一下我实现的功能:能够对加减乘除四个运算符进行运算,支持对括号的运算,但是输入的数字只能在0-9之间,也就是只能是一位数,因为是从字符串里读取的,所以每次只能读一位,否则需要采用别的方法分解式子,这个问题不是这个栈计算器的重点,不做探讨。
我先来讲解一下这个栈计算器的大体思路:
-
从左到右对输入的式子进行扫描,只要是数字,就加入到操作数栈。
-
如果是运算符的话,就要对优先级进行比较了,如果该运算符比运算符栈栈顶元素的优先级要高,则直接入栈,否则,开始循环,每个循环都取出操作数栈的上两个元素,再取出运算符栈的栈顶元素,进行运算,再把结果压进操作数栈,直到碰到左括号,运算符栈已经为空或运算符栈顶元素比当前元素的优先级低这三种情况时,停止循环,把该元素压进运算符栈的栈顶。
-
遇到左括号直接进栈,遇到右括号则不入栈,而是开始对括号里的式子进行计算,计算规则很简单,每次从操作数栈取最上面的俩元素,再取运算符栈的栈顶元素,把计算结果再压入操作数栈,一直循环,直到碰到左括号则停止,把这个左括号出栈。
-
遍历完算式字符串,此时一个操作数栈,一个运算符栈已经满足后缀表达式的计算要求,只要一直循环计算就行了,每个循环和之前的一样,也是取操作数的栈顶部俩元素,再取运算符栈的栈顶元素,计算结果,再把结果压入操作数栈,直到运算符栈为空为止,此时,操作数栈只剩一个元素,也就是这个运算结果。
#include<iostream>
#include<stack>
#include<string>
using namespace std;
class stackCalculator
{
private:
string formulas;
stack<int> s_number;
stack<int> s_operator;
public:
bool inputFormulas()
{
cin >> formulas;
return true;
}
int calculator()
{
int size = formulas.size();
for (int i = 0; i < size; i++)
{
if (formulas[i] > 47 && formulas[i] < 58)
{
s_number.push(int(formulas[i])-48);
}
else if (formulas[i]=='+') //运算符
{
while ((!s_operator.empty())&&s_operator.top()!='(')
{
int var1 = s_number.top();
s_number.pop();
int var2 = s_number.top();
s_number.pop();
char ope = s_operator.top();
s_number.push(getResult(var1,var2,ope));
s_operator.pop();
}
s_operator.push('+');
}
else if (formulas[i] == '-') //运算符
{
while ((!s_operator.empty())&&s_operator.top()!='(')
{
int var1 = s_number.top();
s_number.pop();
int var2 = s_number.top();
s_number.pop();
char ope = s_operator.top();
s_number.push(getResult(var1, var2, ope));
s_operator.pop();
}
s_operator.push('-');
}
else if (formulas[i] == '*') //运算符
{
if (s_operator.empty() || s_operator.top() == '+' || s_operator.top() == '-')
{
s_operator.push('*');
}
else
{
while (s_operator.top()=='*'||s_operator.top()=='/')
{
int var1 = s_number.top();
s_number.pop();
int var2 = s_number.top();
s_number.pop();
char ope = s_operator.top();
s_number.push(getResult(var1, var2, ope));
s_operator.pop();
}
s_operator.push('*');
}
}
else if (formulas[i] == '/') //运算符
{
if (s_operator.empty() || s_operator.top() == '+' || s_operator.top() == '-')
{
s_operator.push('/');
}
else
{
while (s_operator.top() == '*' || s_operator.top() == '/')
{
int var1 = s_number.top();
s_number.pop();
int var2 = s_number.top();
s_number.pop();
char ope = s_operator.top();
s_number.push(getResult(var1, var2, ope));
s_operator.pop();
}
s_operator.push('/');
}
}
else if(formulas[i]=='(')
{
s_operator.push('(');
}
else if (formulas[i] == ')') //直到匹配的左括号出栈为止
{
while (s_operator.top() != '(')
{
int var1 = s_number.top();
s_number.pop();
int var2 = s_number.top();
s_number.pop();
char ope = s_operator.top();
s_number.push(getResult(var1, var2, ope));
s_operator.pop();
}
s_operator.pop();
}
else
{
return 0;
}
}
while (!s_operator.empty())
{
int var1 = s_number.top();
s_number.pop();
int var2 = s_number.top();
s_number.pop();
char ope = s_operator.top();
s_number.push(getResult(var1,var2,ope));
s_operator.pop();
}
if (s_operator.empty())
{
cout << "计算结果为:" << s_number.top() << endl;
}
else
{
cout << "计算失败,式子无效" << endl;
}
return 0;
}
int getResult(int var1, int var2, char oper) //var1是先出栈的,var2是后出栈的
{
if (oper == '+')
{
return var2 + var1;
}
else if (oper == '-')
{
return var2 - var1;
}
else if (oper == '*')
{
return var2 * var1;
}
else if (oper == '/')
{
return var2 / var1;
}
else //不包含我们的四种运算符
{
return 0;
}
}
};
int main()
{
stackCalculator *sc = new stackCalculator();
sc->inputFormulas();
sc->calculator();
system("pause");
return 0;
}