中缀表达式转后缀表达式的过程类似编译过程
转换过程:
当前元素e为数字:输出
当前元素e为运算符:
1.与栈顶运算符进行优先级比较
2.小于等于:将栈顶元素输出,转1
3.大于:将当前元素e入栈
当前元素e为左括号:入栈
当前元素e为右括号:
1.弹出栈顶元素并输出,直至栈顶元素为左括号
2.将栈顶的左括号从栈中弹出
伪代码
while (!exp.isEmpty()) {
QString e = exp.dequeue();
if (isNumber(e)) {
输出: e;
}
else if (isOperator(e)) {
while (priority(e) <= priority(stack.top())) {
输出栈顶元素, stack.pop();
}
stack.push(e);
}
else if (isLeft(e)) {
stack.push(e);
}
else if (isRight(e)) {
while (!isLeft(stack.top())) {
输出栈顶元素, stack.pop();
}
从栈中弹出左括号: stack.pop();
}
}
关键点:转换过程中左右括号是重要标志
如何确保表达式中的括号能够左右匹配?
for (int i = 0; i < len; i++) {
if (exp[i] 为左括号) {
exp[i] 入栈;
}
else if (exp[i] 为右括号) {
if (栈顶元素为左括号) {
将栈顶元素弹出;
}
else
匹配错误;
}
}
bool QCalculatorDec::match(QQueue<QString> &exp) {
bool ret = true;
QStack<QString> s;
for (int i = 0; i < exp.length(); i++) {
if (isLeft(exp[i])) {
s.push(exp[i]);
}
else if (isRight(exp[i])) {
if (!s.isEmpty() && isLeft(s.top())) {
s.pop();
}
else {
ret = false;
break;
}
}
}
return ret;
}
bool QCalculatorDec::transfor(QQueue<QString> &exp, QQueue<QString> &output) {
bool ret = match(exp);
QStack<QString> s;
output.clear();
while (!exp.isEmpty()) {
QString e = exp.dequeue();
if (isNumber(e)) {
output.enqueue(e);
}
else if (isOperator(e)) {
while (!s.isEmpty() && priority(e) <= priority(s.top())) {
output.enqueue(s.pop());
}
s.push(e);
}
else if (isLeft(e)) {
s.push(e);
}
else if (isRight(e)) {
while (!s.isEmpty() && !isLeft(s.top())) {
output.enqueue(s.pop());
}
if (!s.isEmpty()) {
s.pop();
}
} else {
ret = false;
}
}
while (!s.isEmpty()) {
output.enqueue(s.pop());
}
if (!ret) {
output.clear();
}
return ret;
}