-1

我正在为 CLOS 类编写一个函数,该函数反转所述类的对象的列表元素。

我有一个方法可以返回反向列表,但是如何让它将对象的列表设置为该列表?我可以在存储列表的函数中有一个实例变量然后将元素设置为那个吗?或者有没有更简单的方法?

这是现在的方法:

(defun my-reverse (lst)
    (cond ((null lst) ‘())
           (t (append (my-reverse (cdr lst)) (car lst)))))

它传递的对象是 (l my-list),然后访问器是 (my-list-ls l)。

编辑:意识到这cons不适用于 2 个列表。

Edit2:我认为正确的代码是:

(defun my-reverse (l my-list)
        (cond ((null (my-list-ls l) ‘())
               (t (setf (my-list-ls l) (append (my-reverse (cdr (my-list-ls l)))
                                         (car (my-list-ls l)))))))
4

1 回答 1

1

如果要修改对象的槽,则需要将该对象本身传递给您的函数,而不仅仅是要更改的槽的值。

编辑:关于问题的edit2

我假设my-list是类的名称,而您实际上并不想将其传递给函数,对吗?在这种情况下,您应该将 替换defundefmethod。此外,最好在反转整个列表之后只更改一次实例,而不是在每一步更改一次。您可以为此使用内部函数:

(defmethod my-reverse ((l my-list))
  (labels ((inner (list acc)
             (if (endp list)
                 acc
                 (inner (rest list) (cons (first list) acc)))))
     (setf (my-list-ls l) (inner (my-list-ls l) ()))))

编辑2:详细说明

defmethod是定义(多态)方法的替代defun方法。但是,如果您不需要多态性,则可以只使用(defun my-reverse (l)第一行。

labels用于内部函数定义。inner在这里,它定义了一个以两个参数list和命名的内部函数accinner是执行实际逆向的函数,它是尾递归函数,因为逆向与尾递归自然而然地进行。(它可以构建其结果,cons因此具有线性复杂性,而您的解决方案需要append,因此具有二次复杂性,因为cons它本身是恒定的,但是append是线性的。)

firstandrest只是 and 的替代名称car,主要只是 的替代名称cdr,不同之处在于如果它的参数实际上不是一个列表,则会发出错误信号。endpnullendp

最后,最后一行inner以原始列表和空列表作为参数调用,并将结果分配给槽(也称为实例变量)。

于 2011-12-01T07:11:06.540 回答