插入在通用LISP中排序列表

时间:2016-04-30 20:19:07

标签: lisp common-lisp insertion-sort

我有一个关于在LISP中插入列表的代码。我没有IDEA为什么这不起作用..帮助

(defun insertionSort (myList)
    (if (null myList)
        '()
        (insertInPlace (car myList) (insertionSort (cdr myList)))))
enter code her
(defun insertInPlace (e myList)
    (if (null myList)
        (cons e '())
        (if (<= e (car myList))
             (cons e myList)
             (cons (car myList) (insertInPlace e (cdr myList))))))

(setq n (read))
(setq n (- n 1))
(setq d (read))
(setq myList (list d))
(dotimes (i n)
     (setq d (read))
     (setq myList (cons d myList))
)
(write myList)
(insertionSort(myList))

1 个答案:

答案 0 :(得分:1)

排序本身似乎有效,所以问题在于从用户那里读取输入。

首先,您不应该使用SETQ来引入变量。正确的选项可以是LETDEFVAR or DEFPARAMETER。您应该阅读variables一书中关于Practical Common Lisp的章节。但是,在此计划中,您不一定需要使用其中任何一个。

第二个问题是当你调用INSERTIONSORT时,你将参数MYLIST包装在括号中。在Lisps中,括号内的内容通常被视为函数调用。由于MYLIST是变量而不是函数,因此会导致错误。调用它的正确方法当然是:

(insertionSort myList)

请注意,顺便说一句,Lisps中的命名约定是使用小写而不是单词之间的短语而不是camelCase。因此,最好将函数insertion-sort和变量my-list命名为。

READ不是一种非常安全的阅读输入方式。最好将PARSE-INTEGERREAD-LINE一起使用来读取用户的号码。为了获得更好的用户体验,您还应该在阅读输入之前打印某种提示。这是一个小帮手功能:

(defun prompt-for-number (prompt)
  "Display PROMPT and read a number from the user."
  (do ((number nil (parse-integer (read-line *query-io*) :junk-allowed t)))
      (number number)
    (write-string prompt *query-io*)
    (finish-output *query-io*)))

使用它,我们可以要求用户输入数字(并对它们进行排序),如下所示:

(insertionSort (loop 
                  repeat (prompt-for-number "How many numbers: ")
                  collecting (prompt-for-number "Number: ")))