中缀转后缀
转换过程:
当前元素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;
int len = exp.length();
QStack<QString> stack;
for(int i = 0; i < len; i++)
{
if(isLeft(exp[i]) )
{
stack.push(exp[i]);
}
else if(isRight(exp[i]))
{
if(!stack.isEmpty() && isLeft(stack.top()))
{
stack.pop();
}
else
{
ret = false;
break;
}
}
}
return ret;
}
bool QCalculatorDec::transform(QQueue<QString>& exp, QQueue<QString>& output)//中缀转后缀
{
bool ret = match(exp);
QStack<QString> stack;
output.clear();//输出清空
while( ret && !exp.isEmpty())
{
QString e = exp.dequeue();
if(isNumber(e))
{
output.enqueue(e);
}
else if(isOperator(e))
{
while(!stack.isEmpty() && (priority(e) <= priority(stack.top())))
{
output.enqueue(stack.pop());
}
stack.push(e);
}
else if(isLeft(e))
{
stack.push(e);
}
else if(isRight(e))
{
while(!stack.isEmpty() && !isLeft(stack.top()))
{
output.enqueue(stack.pop());
}
if(!stack.isEmpty())
{
stack.pop();
}
}
else
{
ret = false;
}
}
while(!stack.isEmpty())
{
output.enqueue(stack.pop());
}
if(!ret)
{
output.clear();
}
return ret;
}