【问题标题】:Racket: evaluating a tree with arithmetic operatorsRacket:用算术运算符评估树
【发布时间】:2018-05-23 15:10:29
【问题描述】:

我想用算术运算符作为符号来评估一棵树。所以一棵树是:

(define-struct op-tree (op left right))

leftright 可以是数字也可以是 ' 运算符。到目前为止我所拥有的:

(define (eval-op-tree tree)
  (local (
      (define (get-root-op i)
        (cond
          ((symbol=? i '+) +)
          ((symbol=? i '-) -)
          ((symbol=? i '/) /)
          ((symbol=? i '*) *)))
      (define (get-info i)
        (cond
          ((number? i) i)
          ((symbol=? '+ (op-tree-op i)) (+ (get-info (op-tree-left tree)) (get-info (op-tree-right tree))))
          ((symbol=? '- (op-tree-op i)) (- (get-info (op-tree-left tree)) (get-info (op-tree-right tree))))
          ((symbol=? '* (op-tree-op i)) (* (get-info (op-tree-left tree)) (get-info (op-tree-right tree))))
          ((symbol=? '/ (op-tree-op i)) (/ (get-info (op-tree-left tree)) (get-info (op-tree-right tree)))))))
(cond
  ((not (symbol? (op-tree-op tree))) "root has to be an op")
  (else
   ((get-root-op (op-tree-op tree)) (get-info (op-tree-left tree)) (get-info (op-tree-right tree)))))))

这似乎适用于(make-op-tree 'any-operator any-number any-number,但不适用于长度大于 1 且程序永远运行的树...我做错了什么?

【问题讨论】:

  • 寻找你递归到树的各个部分的地方。

标签: functional-programming scheme binary-tree racket


【解决方案1】:

您的代码可以大大简化;例如,如果您的 op 字段可以表示为过程而不是符号,您可以说:

(define (eval-op-tree tree)
  (if (op-tree? tree)
      ((op-tree-op tree) (eval-op-tree (op-tree-left  tree))
                         (eval-op-tree (op-tree-right tree)))
      tree))

然后

> (eval-op-tree (make-op-tree + 1 2))
3
> (eval-op-tree (make-op-tree + 4 (make-op-tree * 7 8)))
60

如果需要使用符号,可以使用关联列表:

(define (eval-op-tree tree)
  (if (op-tree? tree)
      ((cadr (assq (op-tree-op tree)
                   (list (list '+ +) (list '- -) (list '* *) (list '/ /))))
       (eval-op-tree (op-tree-left  tree))
       (eval-op-tree (op-tree-right tree)))
      tree))

然后

> (eval-op-tree (make-op-tree '+ 1 2))
3
> (eval-op-tree (make-op-tree '+ 4 (make-op-tree '* 7 8)))
60

【讨论】:

    【解决方案2】:

    是的,我看到了问题。您有几个小问题。

    • 你有两个完全独立的评估者;一个嵌套在另一个。没有必要有两个单独的。

    • 将您的 get-info 函数移到该本地之外;它不依赖于周围的功能。或者……无论如何,它不应该。 (那是你的 bug。)找到你的 bug 后,你还有一些清理工作要做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-16
      • 2020-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-04
      • 2021-05-02
      • 1970-01-01
      相关资源
      最近更新 更多