首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不能排序列表

不能排序列表
EN

Stack Overflow用户
提问于 2016-11-02 20:15:18
回答 2查看 90关注 0票数 2

我试图使用函数orderlistofcoordinates对坐标列表(如((3 15) (4 15) (5 15) (3 16) (4 16) (5 16)) )进行排序

功能定义如下:

代码语言:javascript
复制
(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背景。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-02 22:21:56

SORT, STABLE-SORT具有以下签名:

代码语言:javascript
复制
sequence predicate &key key => sorted-sequence

返回值是排序的序列。但是,语言规范允许排序函数修改输入中给出的序列,如果原始数据被代码的另一部分引用(但对于临时列表完全没有问题),则可能会产生不良后果。这就是为什么,为了始终安全起见,您的函数首先通过复制来分配一个新的列表。

与函数可以在其作用域外引用变量的语言不同,您不能修改通用Lisp中函数内部不可访问的词法绑定(可以使用动态绑定,即特殊变量)。为了澄清,本地函数可以修改绑定,如下所示:

代码语言:javascript
复制
(let ((x 1)) (lambda () (setf x (* x 2))))

..。但是它不能修改它看不到的绑定,例如在C++中引用变量:

代码语言:javascript
复制
void mutate(int &y)
{
    y = y * 2;
}

void test()
{
    int y = 1;
    mutate(y);
    /* now y equals 2 */
}

在CL中,让调用方负责管理自己的绑定,让函数只返回值。您仍然可以编写一个宏来向用户隐藏该步骤,用户可以选择一个位置,并通过SETF隐式地修改它。例如,一个快速而肮脏的宏可能是:

代码语言:javascript
复制
(defmacro sortf (sequence &rest args)
  `(setf ,sequence (sort ,sequence ,@args))

但我不会为这么简单的情况写一个宏。此外,一个健壮的宏需要检查输入、提供文档以及可能的信号错误消息。

下面是对您的函数的重写,它利用了:key参数sort

代码语言:javascript
复制
(defun sort-coordinates (coordinates)
  (stable-sort (copy-alist coordinates)
               #'>
               :key (lambda (point) 
                      (+ (* (first point) 10) (second point)))))

请注意,我更改了名称,使用破折号分隔单词,并编写了first而不是car

票数 2
EN

Stack Overflow用户

发布于 2016-11-02 20:19:10

问题可能是,您认为您要传递的列表将被修改,相反,该函数将返回一个具有相同协调但排序顺序的新列表。因此,如果希望将该值赋值给一个变量,则需要通过调用此函数获得新值,然后将结果分配给该变量。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40388982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档