13-计算器核心解析算法(中)

1. 括号匹配算法

四则运算中合法的括号:

  • 括号匹配成对出现
  • 左括号必然先于右括号出现

使用栈对左右括号进行中缀到后缀前的检测:

for(int i=0; i<len; i++)
{
    if(exp[i] 为左括号)
        exp[i]入栈;
    else if(exp[i] 为右括号)
    {
        if(栈顶元素为左括号)
            栈顶元素弹出;
        else
            匹配错误;
    }
}

2. 中缀转后缀

转换过程:

-当前元素e为数字:输出
-当前元素e为字符:
	1. 与栈顶运算符进行优先级比较
	2. 小于等于:将栈顶元素输出,转 1
	3. 大于:将当前元素 e 入栈
-当前元素 e 为左括号:入栈
-当前元素 e 为右括号
	1. 弹出栈顶元素并输出,直至栈顶元素为左括号
	2. 将栈顶的左括号从栈中弹出

部分代码实现:

bool (QQueue<QString>& exp, QQueue<QString>& output) // exp是前缀表达式,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  // 其它则是错误情况,虽然这种情况似乎不可能发生,但是在C语言深度剖析中已经解释过,有些很特殊的情况可能会导致意外
        {
            ret = false;
        }
    }

    while( !stack.isEmpty() )  // 将栈中所有的元素入后缀表达式队列
    {
        output.enqueue(stack.pop());
    }

    if( !ret )
    {
        output.clear();
    }

    return ret;
}

3. 总结

  • 后缀表达式是计算复杂表达式的基础
  • 中缀到后缀的转换是基于栈数据结构的
  • 转换过程能够发现表达式中的语法错误
发布了61 篇原创文章 · 获赞 31 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_40794602/article/details/105583734
今日推荐