首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调车场算法

调车场算法
EN

Stack Overflow用户
提问于 2011-04-21 07:45:16
回答 1查看 1.2K关注 0票数 2

我正在用Clojure实现一个中缀计算器,首先我要实现Dijkstra的调车码算法。我认为我已经做得很好了,但是我开了个玩笑,它似乎根本不能很好地处理运算符。正在调用(shunting-yard "3 + 5") => (\3)。就这样。有人能告诉我这里我对操作符的处理出了什么问题吗?

代码语言:javascript
复制
(import '(java.lang.Character))

(defn operator? [sym]
  "Determines if a given token is a mathematical operator."
  (some #{sym} '(\+ \- \* \/ \% \^ \!)))

(defn associativity-of [operator]
  "Determines the associativity of a given mathematical operator."
  (if (some #{operator} '(\+ \- \* \/ \%))
    'left
    'right))

(defn precedence-of [operator]
  "Determines the precedence of a given mathematical operator."
  (case operator
        (\+ \-)    2
        (\* \/ \%) 3
        (\^ \!)    4
                   0))

(defn operator-actions [stmt stack]
  "Actions taken when the next token in the stmt is an operator."
  (let [token-prec  (precedence-of (first stmt))
        token-assoc (associativity-of (first stmt))
        stack-oper  (first stack)
        stack-prec  (precedence-of stack-oper)]
    (cond (or (and (= token-assoc 'left)
                   (<= token-prec stack-prec))
              (and (= token-assoc 'right)
                   (< token-prec stack-prec)))
          (cons stack-oper (shunt stmt (rest stack)))
          :else (shunt (rest stmt) (cons (first stmt) stack)))))

(defn stack-operations [stack]
  "Actions to take if (nil? stmt)"
  (comment "If a left paren is found on the stack, it means
           that there was no right paren to match it, and
           therefore the statement had unbalanced parentheses.")
  (cond (and (not (nil? stack))
             (= (first stack) \()) (print "Unbalanced parentheses.\n")
        (nil? stack) ()
        :else (cons (first stack) (stack-operations (rest stack)))))

(defn shunt [stmt stack]
  (cond (empty? stmt) (stack-operations stack)
        (Character/isDigit (first stmt)) (cons (first stmt)
                                               (shunt (rest stmt) stack))
        (operator? (first stmt)) (operator-actions stmt stack)
        (= (first stmt) \() (recur (rest stmt) (cons (first stmt) stack))
        (= (first stmt) \)) (if (= (first stack) \()
                              (recur (rest stmt) (rest stack))
                              (cons (first stack) (shunt stmt (rest stack))))))

(defn shunting-yard [stmt]
  (shunt stmt ()))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-04-21 09:01:10

我实际上不知道Shunting-Yard算法(刚才在维基百科上节省了2分钟),但我看到的一个问题是shunt不处理空格。因为下一个字符是\space,所以它读取您的\3、递归和退出。如果stmt没有空格,也就是"3+5",你会得到一个StackOverflowError,但我想这就是进步。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5737903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档