如何在lisp中按升序排列3个数字的排序列表

时间:2016-09-25 10:45:32

标签: list function lisp

我正在尝试在lisp中按升序排列3个数字的排序列表。 但我得到的错误就像"错误的参数数量如果"在编译和加载时。

(defun order (n1 n2 n3)
     (if (>= n1 n2)
        (progn(progn(if (>= n1 n3) 
            (progn(if (>= n2 n3) (progn(setf max n1) (setf mid n2) (setf min n3))     (progn(setf max n1) (setf mid n3) (setf min n2))))
        (progn(setf max n3) (setf mid n1) (setf min n2))
        )))
         (progn(progn(if (< n1 n3) 
             (progn(if (>= n2 n3) (progn(setf max n2) (setf mid n3) (setf min n1))     (progn(setf max n3) (setf mid n2) (setf min n1))))
        ((setf max n2) (setf mid n1) (setf min n3))
        )))

    ))
    (list min mid max)
)

3 个答案:

答案 0 :(得分:2)

不是随机输入并希望它有效,一个好的方法是用英语写下你需要实现的算法来订购三个数字。然后,如果幸运的话,可以直接将其转换为代码。

所以

订购a,b,c:

  • 如果a&lt; = c
    • 如果a&lt; = b(a至少,我们需要订购b和c)
      • 如果b <= c,答案是b c,否则答案是c b
    • 其他(a&lt; = c和a&gt; b,我们有订单)答案是b a c
  • 其他(a&gt; c)
    • 如果b&lt; = c(a&gt; c&b; = c所以我们有订单)答案是b c a
    • else(a&gt; c,b&gt; c,我们需要订购a和b)
      • 如果&lt; = b答案是c a b否则答案是c b a

现在把它变成Lisp。记住if的语法是(if test true-result false-result),其中true-resultfalse-result是表达式。

答案 1 :(得分:2)

这是一个可能的解决方案:

(defun order (min mid max)
  (when (< mid min)
    (rotatef mid min))
  (if (< max min)
      (rotatef max mid min)
      (when (< max mid)
        (rotatef mid max)))
  (list min mid max))

首先,我们假设这三个参数已经是正确的顺序,如果不是这样,我们通过使用rotatef来改变它们,https://jsfiddle.net/f1apoya1/7/是一个原始函数,它交换两个变量或旋转三个或更多变量。

如有必要,第一个when会更正minmid之间的相对顺序,如果mid小于min,则会对其进行更改。

当我们知道min实际上小于mid时,我们会尝试以这种方式将max放在正确的位置:

  • 首先,如果它小于min,这意味着它是三者中较小的一个,我们适当地旋转三个变量,

  • 否则,它可能位于minmid之间,在这种情况下,我们会交换midmax个变量。如果它大于或等于mid,则不必进行交换,并且三个变量已按正确的顺序包含值。

答案 2 :(得分:0)

气泡排序再现:

(defun order (a b c)
      (when (> a b) (rotatef a b))
      (when (> b c) (rotatef b c))
      (when (> a b) (rotatef a b)) 
      (list a b c))