我在读实用的通用Lisp。在第11章,中,它提到了有关排序的内容:
通常,在对序列进行排序之后,您不会关心序列的未排序版本,因此允许
SORT和STABLE-SORT在排序过程中销毁序列是有意义的。但这确实意味着您需要记住编写以下内容: (setf序列(排序my-sequence #'string<))
我尝试了以下代码:
CL-USER> (defparameter *a* #( 8 4 3 9 5 9 2 3 9 2 9 4 3))
*A*
CL-USER> *a*
#(8 4 3 9 5 9 2 3 9 2 9 4 3)
CL-USER> (sort *a* #'<)
#(2 2 3 3 3 4 4 5 8 9 9 9 9)
CL-USER> *a*
#(2 2 3 3 3 4 4 5 8 9 9 9 9)在这段代码中,我们可以看到变量*a*已被sort函数更改。
那为什么书上说那是做作业所必需的?
我用的是SBCL + Ubuntu 14.04 + Emacs +石灰
编辑:,在@Sylwester的注释之后,我添加了*a*的计算,因此很明显,该值已经更改。
发布于 2015-04-18 04:21:21
如果您希望变量随后包含排序序列的适当值,则有必要执行赋值。如果您不关心这一点,并且只需要sort的返回值,则不需要赋值。
这有两个原因。首先,允许实现使用非破坏性复制来实现破坏性操作.其次,列表上的破坏性操作可以改变内容,从而传递到操作中的值不再指向序列的第一个缺点。
下面是第二个问题的示例(在SBCL下运行):
(let ((xs (list 4 3 2 1)))
(sort xs '<)
xs)
=> (4)如果我们加上作业:
(let ((xs (list 4 3 2 1)))
(setf xs (sort xs '<))
xs)
=> (1 2 3 4)发布于 2015-04-18 04:23:32
变量不能被排序函数更改,因为排序函数根本不知道变量的情况。
所有排序函数得到的都是向量或列表,而不是变量。
在通用Lisp中,排序函数可能具有破坏性。当它得到一个用于排序的向量时,它可以返回相同的向量或一个新的向量。--这取决于实现。在一个实现中,它可能返回相同的向量,而在另一个实现中,它可能返回一个新的向量。但无论如何,它们都会被分类。
如果有一个变量,它指向一个序列,并且作者期望它在排序后指向一个排序序列:将变量设置为排序操作的结果。否则,可能会出现这样的情况:在可能具有破坏性的排序之后,变量将不会指向排序结果,但仍然指向未排序或其他更改的序列。在向量的情况下,这可以是旧的和未排序的向量。
记住,是唯一可以确定的:排序函数返回一个排序序列作为它的值。
https://stackoverflow.com/questions/29712654
复制相似问题