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



我正在尝试在lisp中按升序列出3个数字的排序列表。但在编译和加载时,我遇到了类似"if的参数数量不正确"的错误。

(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)
)

这里有一个可能的解决方案:

(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来更改它们,CCD_1是一个交换两个变量或旋转三个或更多变量的基函数。

如果需要,第一个when校正minmid之间的相对顺序,如果mid小于min,则交换它们。

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

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

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

一个好的方法是用英语写下你需要实现的排序三个数字的算法,而不是随机键入并希望它能起作用。然后,如果你幸运的话,你可以直接把它变成代码。

所以

订购a、b、c:

  • 如果a<=c
    • 如果a<=b(a是最小的,我们需要订购b和c(
      • 如果b<=c的答案是b c,否则答案是c b
    • 否则(a<=c和a>b,我们有一个顺序(答案是b a c
  • 其他(a>c(
    • 如果b<=c(a>c和b<=c,所以我们有一个顺序(答案是bca
    • 否则(a>c,b>c,我们需要订购a和b(
      • 如果a<=b答案是c a b其他答案是c b a

现在把它变成Lisp。记住CCD_ 16的语法是CCD_ 17,其中CCD_。

气泡排序格式副本:

(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))

最新更新