一、中缀转后缀

中缀表达式转后缀表达式的过程类似编译过程
四则运算符表达式中的括号必须匹配
根据运算符优先级进行转化
转换后的表达式没有括号
转换后可以顺序的计算出最终结果

转换过程:
当前元素e为数字:输出

当前元素e为运算符:
1.与栈顶运算符进行优先级比较
2.小于等于:将栈顶元素输出,转1
3.大于:将当前元素e入栈

当前元素e为左括号,入栈
当前元素e为右括号:
1.弹出栈顶元素并输出,直至栈顶元素为左括号
2.将栈顶的左括号从栈中弹出。
image.png
关键点:转换过程中左右括号是重要标志。

二、括号匹配算法

合法的四则运算表达式中:
括号匹配成对出现
左括号必然先于右括号出现

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 && stack.isEmpty();
}

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;
}

四、小结

后缀表达式是程序计算表达式的基础
中缀到后缀的转换是基于栈数据结构的
转换过程能够发现表达式中的语法错误


YingLi
6 声望4 粉丝

From zero to hero.