计算机如何读懂四则运算表达式? 9.3 + ( 3 - -0.11 ) * 5
后缀表达式-
人类习惯的数学表达式叫做中缀表达式
-
另外,还有一种将运算符放在数字后面的后缀表达式
-
实例:
5 + 3 => 5 3 +
1 + 2 * 3 => 1 2 3 * +
9 + ( 3 - 1 ) * 5 => 9 3 1 - 5 * +
- 中缀表达式符合人类的阅读和思维习惯
- 后缀表达式符合计算机的运行方式
- 消除了中缀表达式中的括号
- 同时保留中缀表达式中的运算优先级
-
解决方案
1.将中缀表达式进行数字和运算符的分离
2.将中缀表达式转换为后缀表达式
3.通过后缀表达式计算最终结果
-
所要计算的中缀表达式中包含
- 数字和小数点 [0 - 9 或 .
- 符号位 [ + 或 - ]
- 运算符 [ +,-,*,/ ]
- 括号 [ ( 或 ) ]
-
思想:以符号作为标志对表达式中的字符逐个访问
-
定义累计变量num
-
当前字符 exp[i] 为数字或小数点时:
- 累计:num += exp[i]
-
当前字符为 exp[i] 为符号时:
-
num为运算数,分离并保存
-
若 exp[i] 为正负号:累计符号位 + 和 -:num += exp[i]
-
若 exp[i] 为运算符:分离并保存
-
-
-
伪代码
for (int i = 0; i < exp.length(); i++) {
if (exp[i] 为数字或小数点) {
累计: num += exp[i];
}
else if (exp[i] 为符号) {
if (num != "") {
分离并保存运算数: num
}
if (exp[i] 为正好或负号) {
符号位累计: num += exp[i];
}
else {
分离并保存运算符: exp[i];
}
}
}
-
难点:
-
如何区分正负号与加号和减号?
- +和-在表达式的第一个位置
- 括号后的 + 和 -
- 运算符后的 + 和 -
-
+9 + (-3 - -1) * -5
-
#include#include class QCalculatorDec { protected: bool isDigitOrDot(QChar c); bool isSymbol(QChar c); bool isSign(QChar c); bool isNumber(QString s); bool isOperator(QString s); bool isLeft(QString s); bool isRight(QString s); int priority(QString s); QQueue split(const QString& exp); public: QCalculatorDec(); };
#include "QCalculatorDec.h" #include小结bool QCalculatorDec::isDigitOrDot(QChar c) { return (('0' <= c) && (c <= '9')) || (c == '.'); } bool QCalculatorDec::isSymbol(QChar c) { return isOperator(c) || (c == '(') || (c == ')'); } bool QCalculatorDec::isSign(QChar c) { return (c == '+') || (c == '-'); } bool QCalculatorDec::isNumber(QString s) { bool ret = false; s.toDouble(&ret); return ret; } bool QCalculatorDec::isLeft(QString s) { return (s == "("); } bool QCalculatorDec::isRight(QString s) { return (s == ")"); } int QCalculatorDec::priority(QString s) { int ret = 0; if ((s == '+') || (s == '-')) { ret = 1; } if ((s == '*') || (s == '/')) { ret = 2; } return ret; } QQueue QCalculatorDec::split(const QString &exp) { QString num = ""; QString pre = ""; QQueue ret; for (int i = 0; i < exp.length(); i++) { if (isDigitOrDot(exp[i])) { num += exp[i]; pre = exp[i]; } else if (isSymbol(exp[i])) { if (num != "") { ret.enqueue(num); num.clear(); } if (isSign(exp[i]) && ((pre == "") || (isLeft(pre)) || (isOperator(pre)))) { num += exp[i]; } else { ret.enqueue(exp[i]); } pre = exp[i]; } } if (!num.isEmpty()) { ret.enqueue(num); } return ret; } bool QCalculatorDec::isOperator(QString s) { return (s == '+') || (s == '-') || (s == '*') || (s == '/'); } QCalculatorDec::QCalculatorDec() { QQueue r = split("-9.3 + ( 3 - 0.11 ) * 5"); for (int i = 0; i < r.length(); i++) { qDebug() << r[i]; } }
- QString中的每个字符为QChar
- Qt中提供了开发中不可或缺的数据结构类
- 四则运算表达式的计算分为三个步骤
- 数字和符号分离
- 中缀表达式转后缀表达式
- 根据后缀表达式计算结果



