栈的特性:后进先出(Last In First Out)-----》数据结构
中缀:+9.11 +(-3 - -1)* -5 ;
分离数字与运算符:+9.11 、+、( 、-3 、 - 、 -1 、)、* 、 -5 ;
后缀:+9.11 、-3 、 -1 、- 、-5 、* 、+ ;
中缀转后缀过程:
当前元素为数字,输出,作为后缀表达式的一部分;
如果当前运算符,比栈顶运算符优先级低(小于等于)时,将栈顶元素输出,作为后缀表达式的一部分;
。。。。 。。。。 。。。。。 大于时,将当前元素入栈 ,栈主要用来保存中缀表达式的运算符
如果为左括号,入栈,栈用来保存符号;
。。为右括号,将栈顶元素输出,作为后缀表达式的一部分,直到栈顶元素为左括号,将其弹出不要了;
左括号与右括号就是在转换过程中被丢弃。
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() ) //栈作为数据结构来使用,有必要检查:1.检查栈不为空?
{
output.enqueue(stack.pop()); //将栈中的所有放到输出队列中,后缀只是抛弃了括号,其他不会删
}
if( !ret ) //为安全性编程,如果转换失败,就要清空输出队列
{
output.clear();
}
return ret;
}