【问题标题】:Minimum element in a tree树中的最小元素
【发布时间】:2016-05-24 05:06:27
【问题描述】:

我想在 Lisp 中的非线性列表(编辑:树)中找到最小元素(在任何级别)。我写了类似的东西:

(defun minimum (l)
  (cond
    ((null l) 99999)
    ((atom (car l)) (min (minimum (cdr l)) 99999))
    ((numberp (car l)) (min (car l) (minimum (cdr l))))
    (T (min (minimum (cdr l)) (minimum (Car l))))))

但是,它不起作用(因为非数字原子的条件,我猜......)。有谁知道如何修复此代码?提前致谢。

【问题讨论】:

    标签: tree lisp common-lisp minimum


    【解决方案1】:

    您的 numberp 案例永远不会执行,因为 atom 案例首先被测试,并且数字是原子。所以每个数字都被 99999 替换。把 numberp 放在第一位。

    您的代码的另一个问题是,如果树中的最小数字大于 99999,它将找不到最小的数字。要在不过多更改代码的情况下修复它,您需要自己的 min 版本支持无穷大的表示:

    (defun inf-min (a b)
         (cond ((eq a :infinity) b)
               ((eq b :infinity) a)
               ((< a b) a)
               (t b)))
    

    然后,将min 替换为inf-min,将99999 替换为:infinity

    【讨论】:

    • (null l) 之后添加一个(atom l) 可以支持不正确的列表。
    【解决方案2】:

    使用 99999 真的是一种 hack(不是好的那种 hack),请不要这样做。使用:infinity 会好一些,但在给出空列表时,您是否希望结果为:infinityloop 方法更好,但是当列表为空时,minimize 返回 0,这通常不是我们想要的。

    对于零值,minimum 函数是未定义的,所以我将定义一个tree-min 函数,当树不包含数字时,结果为nil。像这样的:

    (defun tree-min (tree)
      (typecase tree
        ;; base case with numbers
        (number tree)
    
        ;; string are sequences too, but don't iterate over them.
        (string nil) 
    
        ;; vectors and lists
        (sequence (reduce (lambda (m e)
                            (let ((em (tree-min e)))
                              (or (and m em (min em m)) ; Eminem?
                                  em)))
                          tree
                          :initial-value nil))))
    

    该函数静默跳过任何非数字元素。以下是一些示例:

    (tree-min #(3 2 nil (2 1 -20) 100 20 ))
    => -20
    
    (tree-min nil)
    => nil
    
    (tree-min '(a 20))
    => 20
    

    在实践中,您可以将此函数推广为像extremum 那样采用比较函数。

    【讨论】:

      【解决方案3】:
      (defun minimum (tree)
          (loop for item in tree
               if (consp item) minimize (minimum item)
               else if (numberp item) minimize item))
      

      【讨论】:

      猜你喜欢
      • 2018-06-11
      • 2016-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-21
      相关资源
      最近更新 更多