四则运算表达式求值
本文将讨论什么是运算表达式,如何用代码实现中缀表达式转后缀表达式、前缀表达式,以及对后缀表达式的求值。
关于算术表达式
通常我们所看到的算术表达式,运算符总是在两个操作数中间,这样的表达式叫做中缀表达式。与之对应的还有前缀表达式,后缀表达式。中缀表达式易于人的理解,但是使用时往往涉及到运算符的优先级问题,并且需要对括号进行处理。编译系统中对中缀形式的算术表达式的处理方式是: 先把中缀表达式转换成后缀表达式,再进行计算。
表达式的转换和求值方法简述
前缀表达式求值方法
从右往左扫描表达式,遇到数字则压栈,遇到操作符则从栈顶取出两个数进行计算,并将结果压回栈中。
后缀表达式求值方法
方法与前缀表达式求值方法相似,但扫描方向变成从左往右。
中缀表达式求值方法
中缀表达式需要转换成前序表达式或后续表达式。
中缀式转后缀式方法
维护两个栈,运算符栈s1 和 结果栈s2。从左到右扫描表达式。遇到数字直接放s2;遇到操作符时,若:s1为空、自身或s1顶部为’(’、优先级比s1顶部高,则将操作数压入s1,否则将s1顶元素转移到s2,然后继续与最新的s1顶部对比; 若当遇到括号 ‘)’ 时,将s1中第一个’('之前的元素转移到s2中,并丢弃剩余的一对括号。遍历完毕后若s1有剩余则将其转移到s2,s2的逆序弹出结果为对应的后缀表达式。
中缀式转前缀式方法
过程可以参考中缀转后缀的过程,其中差别:
扫描方向是从右往左;
‘(’ 和 ‘)’ 的处理方式要倒转;
与s1顶部对比时,优先级更高或相等都压到s1顶部(之前不包括相等);
最终结果栈的弹出结果不用转逆序;
参考代码:
以下的代码使用C++实现上面提及到的转换和求值过程,支持包括浮点数的四则运算。
#define STRINGS vector<string> //字符串数组类型别名
//对中缀表达式进行词法分析,分开每个元素放到数组里面,元素包括数字和运算符两大类
//input example: 1+2*3 10.5+((21+34)*4.5)-56.6
STRINGS splitFormula(string formular){
STRINGS result;
string buf;
regex reg("\\d+(\\.\\d+)?|[\\+\\-\\*\\/\\(\\)]");
smatch matchRes;
while (regex_search(formular, matchRes, reg)){
result.push_back(matchRes.str());
formular = matchRes.suffix().str();
}
return result;
}
//枚举表达式中每项元素的类型
enum eleType{
IntType, FloatType, OpeType, Unknow};
//判断表达式中元素的类型
eleType judgeType(string ele){
regex numReg("^\\d+$");
if (regex_match(ele, numReg)){
return IntType;
}
regex numReg1("^\\d+(\\.\\d+)?$");
if (regex_match(ele, numReg1)){
return FloatType;
}
regex opeReg("^[\\+\\-\\*\\/\\(\\)]$");
if (regex_match(ele, opeReg)){
return OpeType;
}
return Unknow;
}
//判断操作符的优先级
int getPriority(string ope){
if (ope == "+" || ope == "-"){
return 1;
}
if (ope == "*" || ope == "/"){
return 2;
}
return 4;
}
//中缀表达式转后缀表达式
STRINGS inFixToSurFix(STRINGS seq){
stack<string> tmpRes, tmpOpe;
for

本文探讨了中缀、前缀和后缀运算表达式,讲解了如何将中缀表达式转换为后缀表达式并进行求值。通过C++代码实现了四则运算表达式的转换和计算,支持浮点数操作。
最低0.47元/天 解锁文章
9235

被折叠的 条评论
为什么被折叠?



