我试图使用函数orderlistofcoordinates对坐标列表(如((3 15) (4 15) (5 15) (3 16) (4 16) (5 16)) )进行排序
功能定义如下:
(defun orderlistofcoordinates (coordlist)
;; order list of coordinates
(stable-sort (copy-alist coordlist)
#'(lambda (x y)
(> (+ (* (car x) 10)
(second x))
(+ (* (car y) 10)
(second y))))))我理解这个函数正在做什么,但是我如何为一个变量分配一个坐标列表,然后使用这个函数对其进行排序呢?
我很难进入Lisp,因为我是C背景。
发布于 2016-11-02 22:21:56
SORT, STABLE-SORT具有以下签名:
sequence predicate &key key => sorted-sequence返回值是排序的序列。但是,语言规范允许排序函数修改输入中给出的序列,如果原始数据被代码的另一部分引用(但对于临时列表完全没有问题),则可能会产生不良后果。这就是为什么,为了始终安全起见,您的函数首先通过复制来分配一个新的列表。
与函数可以在其作用域外引用变量的语言不同,您不能修改通用Lisp中函数内部不可访问的词法绑定(可以使用动态绑定,即特殊变量)。为了澄清,本地函数可以修改绑定,如下所示:
(let ((x 1)) (lambda () (setf x (* x 2))))..。但是它不能修改它看不到的绑定,例如在C++中引用变量:
void mutate(int &y)
{
y = y * 2;
}
void test()
{
int y = 1;
mutate(y);
/* now y equals 2 */
}在CL中,让调用方负责管理自己的绑定,让函数只返回值。您仍然可以编写一个宏来向用户隐藏该步骤,用户可以选择一个位置,并通过SETF隐式地修改它。例如,一个快速而肮脏的宏可能是:
(defmacro sortf (sequence &rest args)
`(setf ,sequence (sort ,sequence ,@args))但我不会为这么简单的情况写一个宏。此外,一个健壮的宏需要检查输入、提供文档以及可能的信号错误消息。
下面是对您的函数的重写,它利用了:key参数sort
(defun sort-coordinates (coordinates)
(stable-sort (copy-alist coordinates)
#'>
:key (lambda (point)
(+ (* (first point) 10) (second point)))))请注意,我更改了名称,使用破折号分隔单词,并编写了first而不是car。
发布于 2016-11-02 20:19:10
问题可能是,您认为您要传递的列表将被修改,相反,该函数将返回一个具有相同协调但排序顺序的新列表。因此,如果希望将该值赋值给一个变量,则需要通过调用此函数获得新值,然后将结果分配给该变量。
https://stackoverflow.com/questions/40388982
复制相似问题