2

我试图完成这个练习;

Write a Lisp function that takes as input a list of elements, such as (A B C)

,并返回一个列表,其中每个元素的位置都跟在它后面,例如 (A 1 B 2 C 3)

我试图用两个函数来做,但是它不能正常工作,我只是得到相同的列表。这是我的代码:

(defun insert (index var userList)
    (if (or (eql userList nil) (eql index 1))
            (cons var userList)
            (cons (car userList) (insert (- index 1) var (cdr userList)))))


(defun insertIndex (userList)
    (setq len (length userList))
    (loop for x from 1 to len
        do (insert x x userList)))

插入函数本身似乎可以正常工作,但似乎它对循环没有任何作用。我是新的 lisp,任何帮助将不胜感激,在此先感谢。

4

2 回答 2

3

Lisp 中的位置从 0 开始。在 insertIndex 中,变量 len 没有定义。LOOP 不返回任何有用的值。

如果你想用递归来解决它,解决方案要简单得多。

您需要测试结束条件。如果列表为空,则返回空列表。

否则创建一个新列表,其中包含 FIRST 元素、当前位置以及在列表其余部分上调用函数的结果,并且位置加一。

(LIST* 1 2 '(3 4)) is shorter for (cons 1 (cons 2 '(3 4))).

这是具有本地功能的示例。使用 DEFUN 创建顶级函数现在是您的任务。您只需要稍微重写代码。LABELS 引入了一个潜在的递归局部函数。

(labels ((pos-list (list pos)
           (if (null list)
               '()
               (list* (first list)
                      pos
                      (pos-list (rest list) (1+ pos))))))
  (pos-list '(a b c d e f) 0))
于 2011-01-31T00:34:20.017 回答
2

insertIndex您的函数的主要问题是do子句 ofloop仅用于副作用,它不会更改loop. (而且你insert的没有副作用。)loop将元素添加到列表返回值的正确子句是collect. (还有appendnconc加入多个列表。)

这是一个工作函数:

(defun insert-index (list)
  (loop for elt in list and i from 1
    collect elt
    collect i))

insert您对and函数行为的全部期望insertIndex似乎存在缺陷。您需要获得一个更清晰的心智模型,了解哪些功能是副作用,哪些不是,以及您是否需要副作用来解决某些特定问题。

此外,您不应该setq在 Common Lisp 中调用未定义的变量。你需要先使用let引入一个新的局部变量。

小点:CamelCase 在 Lisp 中非常不习惯。在标识符中分隔单词的惯用方法是使用破折号,就像我在代码示例中所做的那样。而且你不需要做(eql something nil),有一个特殊的null功能来检查是否有东西nil,例如(null something)

于 2011-02-03T02:43:14.653 回答