2016-09-25 72 views
-3

我正在尝试在lisp中以升序排列3个数字的排序列表。 但编译和加载时出现错误,如“if的错误数量”。如何在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) 
) 
+0

真正的好奇心:你认为'progn'有什么用? – coredump

+0

我认为预测是不能发挥功能,但我不确定.... –

+1

downvoted因为代码没有缩进/格式在任何有用的方式。这是不可读的。 –

回答

1

比随机打字,希望它的工作原理相反,一个好的办法是写下来,在英语,你需要实现订购三个数字的算法。那么,如果你幸运的话,你可以直接把它变成代码。

所以

要订购,B,C:

  • 如果如果<一个< = C
    • = B(A是最不重要的,我们需要订购b和c )
      • 若b < = C答案是ABC,否则答案是ACB
    • 其他(一个< = c和A> B,我们有一个数量级)的答案是BAC
  • 否则(A> C)
    • 若B < = C(A> C和b < = C,所以我们有一个订单)的答案是BCA
    • 否则(A> C,b> C,我们需要订购和b)
      • 如果< = b的答案是驾驶室别人的答案是CB一个

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

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,原始功能交换两个变量或旋转三个或更多变量。

第一when校正,如果必要的话,minmid,交换它们之间的相对顺序,如果是mid小于min

当我们知道min实际上比mid少,我们尽量把max在正确的地方是这样的:

  • 第一,如果是小于min,这意味着它是三个小,又适当旋转三个变量,

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