调度场算法(Shunting Yard Algorithm)

介绍

在计算机科学领域,调度场算法是一个用于解析数学表达式的方法,尤其是中缀表达式。该算法可以既可以输出一个后缀记号法的字符串页可以输出一个抽象的语法树结构。这个算法的发明者是Edsger Dijkstra,将其命名为调度场算法是由于该算法的操作与铁路调度场的操作类似。

与逆波兰标记法的实现类型,调度场算法也是基于栈的。中缀表达式是人们常用的数学记号法,例如,“3+4”,“3+4X(2-1)”。为了实现转换,需要两个文本变量, 一个是输入变量,一个是输出变量。还有一个用于保存尚未添加到输出队列的操作符的栈。为了实现装换,程序依次读入每一个符号,根据符号的类型(操作数、操作符、括号等)分别进行处理。上面例子的结果分别是“3 4 +”和“3 4 2 1 - X +”。

后来,调度场算法被推广到用于操作符优先级的解析。

一个简单的转换

1、输入:3+4;

2、将字符‘3’,属于操作数类型,推入输出队列;

3、将字符‘+’,属于操作符,推入操作符栈;

4、将字符‘4’,属于操作数类型,推入输出队列;

5、完成输入表达是的读入,从栈中弹出操作符,推入输出队列;

6、输出结果为 “3 4 +”。

规则:

  • 当读到操作数类型字符时,都会被推入输出队列。
  • 读到输入表达式末尾后,弹出保存操作符的栈中的所有操作符,推入到输出队列。

图形示例

算法的图形示例使用了三路铁轨连接。每次处理一个符号,如果该符号是一个变量或者数字,直接移动到输出队列,如图a),c),e),h);如果该符号是一个操作符,压入操作符栈中,如图b),d),f);如果操作符的优先级低于栈顶的操作符或者与栈顶操作符优先级相等并且该操作符是左结合的,那么将栈顶的操作符从栈顶弹出并推入输出队列,如图g);读到输入字符串结尾,将栈中所有的操作符弹出并推入到输出队列,如图i)。

算法过程

重要的项:Token(标记),Function(函数),Operator associativity(操作符结合性),Precedence(优先级)

注,实现中没有实现复合函数,具有可变数目参数的函数和单目运算符

while there are tokens to be read:
    read a token.
    if the token is a number, then:
        push it to the output queue.
    if the token is a function then:
        push it onto the operator stack 
    if the token is an operator, then:
        while ((there is a function at the top of the operator stack)
               or (there is an operator at the top of the operator stack with greater precedence)
               or (the operator at the top of the operator stack has equal precedence and is left associative))
              and (the operator at the top of the operator stack is not a left bracket):
            pop operators from the operator stack onto the output queue.
        push it onto the operator stack.
    if the token is a left bracket (i.e. "("), then:
        push it onto the operator stack.
    if the token is a right bracket (i.e. ")"), then:
        while the operator at the top of the operator stack is not a left bracket:
            pop the operator from the operator stack onto the output queue.
        pop the left bracket from the stack.
        /* if the stack runs out without finding a left bracket, then there are mismatched parentheses. */
if there are no more tokens to read:
    while there are still operator tokens on the stack:
        /* if the operator token on the top of the stack is a bracket, then there are mismatched parentheses. */
        pop the operator from the operator stack onto the output queue.
exit.

为了分析该算法运行时间复杂度,需要注意的是每个符号只需要读取一次,每个操作数,函数和操作符输出一次,每个函数,操作符和括号都会推入和弹出栈一次,因此,每个记号,至多执行固定数目的运算,运行时间复杂度为o(n),线性与如数字符串的长度。

详细示例


https://en.wikipedia.org/wiki/Shunting-yard_algorithm

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值