博主16年4.19去面腾讯实习生,其中一个问题是让写一个函数求四则运算表达式的值,输入是字符串,输出为表达式结果。当时只记得这是数据结构里堆栈的应用,表达式要变顺序,但是实现就想不起来了,自然程序写的一塌糊涂,结果也就呵呵了。回来之后翻书查资料把程序写出来,供大家参考。程序主要思路参考CSDN中作者wzfxyer 的文档 点击打开链接 。
首先,明确两个个概念,“中缀表达式”和 ”后缀表达式“一般的运算表达式。例如”9+(3-1)*3+10/2“,这是中缀表达式,而”9 3 1- 3 *+10 2 / +“则是后缀表达式,计算后缀表达式的值,先把数字入栈,遇到操作符则栈顶两个数字出栈运算,然后再把结果存入栈中,比如,计算该后缀表达式的过程为 ,①9,3,1入栈,遇到‘-’,计算3-1=2,将2入栈,此时栈中为9,2。②接着3入栈,栈中为9,3,2,然后遇到‘*’,栈顶两个数字3,2出栈计算3*2=6,将6入栈,此时栈中为9,6。③接着遇到‘+’号,栈顶两元素出栈,计算9+6=15,将15入栈,此时栈中为15。④,然后10,2,入栈,最后遇到‘/’,栈顶两数字10,2出栈计算,10/2 =5,并将5入栈,此时栈中为15,5。⑤遇到操作符‘+’,将栈顶两元素弹 出,计算15+5 = 20.入栈再出栈,即为最后结果。
所以计算表达式的值有两个关键步骤,一是将中缀表达式转为后缀表达式;二是计算后缀表达式的值。中缀表达式转后缀表达式的思想是,从左到右遍历表达式中的每个数字和符号,遇到数字则输出,遇到符号,则要比较其与栈顶元素的优先级,若优先级低于栈顶元素,则将栈顶元素依次输出并将该元素入栈;若优先级高于栈顶元素则入栈;若是遇到左括号,入栈,入栈后的左括号优先级低于+ - * / ;若是遇到右括号,则将栈顶元素依次输出,直到遇到左括号。最后再将栈中元素依次输出,最终输出结果即为后缀表达式。
程序思想: 定义一个类ExpressionType ,有三个主要函数,一是将字符串中的数字和字符分割出来放到队列中,二是中缀变后缀函数,三是计算后缀表达式的值。其他函数有计算字符串长度,检测左括号和右括号是否匹配(只是为了保证原始字符串没有问题),重载操作符+(是为了把字符串赋给类的变量),两个构造函数。还有一个私有变量,m_string,既要计算的表达式字符串。
我用VS08新建一个空项目,添加一个ExpressionType.h文件,代码如下:
#include <string>
#include <stack>
#include <queue>
using namespace std;
class ExpressionType
{
public:
ExpressionType();
ExpressionType(string m_string);
void operator =(string m_string);
double Calculate();
private:
queue<string> DivideExpressionToItem();
stack<string> ChangeToStuff();
bool IsWellForm();
int Size();
private:
string m_string;
};
添加一个ExpressionType.cpp文件,代码如下:
#include <iostream>
#include "ExpressionType.h"
using namespace std;
ExpressionType::ExpressionType() {
m_string = "";
}
ExpressionType::ExpressionType(string m_string)
{
this->m_string = m_string;
}
void ExpressionType::operator =(string m_string)
{
this->m_string = m_string;
}
int ExpressionType::Size()
{
return m_string.size();
}
bool ExpressionType::IsWellForm()
{
stack<char> stack;