Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 我需要合并两个列表,对它们进行排序并删除重复项。有更好的方法吗?_Algorithm_Sorting_Lisp_List - Fatal编程技术网

Algorithm 我需要合并两个列表,对它们进行排序并删除重复项。有更好的方法吗?

Algorithm 我需要合并两个列表,对它们进行排序并删除重复项。有更好的方法吗?,algorithm,sorting,lisp,list,Algorithm,Sorting,Lisp,List,我有两个未排序的列表,我需要生成另一个已排序的列表,其中所有元素都是唯一的 元素可以在两个列表中出现多次,并且它们最初是未排序的 我的函数如下所示: (defun merge-lists (list-a list-b sort-fn) "Merges two lists of (x, y) coordinates sorting them and removing dupes" (let ((prev nil)) (remove-if

我有两个未排序的列表,我需要生成另一个已排序的列表,其中所有元素都是唯一的

元素可以在两个列表中出现多次,并且它们最初是未排序的

我的函数如下所示:

(defun merge-lists (list-a list-b sort-fn)
    "Merges two lists of (x, y) coordinates sorting them and removing dupes"
    (let   ((prev nil))
        (remove-if
            (lambda (point)
                (let   ((ret-val (equal point prev)))
                    (setf prev point)
                    ret-val))
            (sort
                (merge 'list list-a list-b sort-fn) ;'
                 sort-fn))))
有没有更好的方法实现同样的目标

电话示例:

[CL]> (merge-lists '(9 8 4 8 9 7 2) '(1 7 3 9 2 6) #'>)
  ==> (9 8 7 6 4 3 2 1)

我想我应该首先对这两个列表分别排序,然后用一个函数合并它们,该函数也可以跳过重复项。这应该快一点,因为它需要两个列表少遍历一次


注:我怀疑它能做得更快,因为你基本上总是需要至少一次排序和一次合并。也许你可以将两者结合在一个函数中,但如果这没有(很大)区别的话,我不会感到惊讶。

听起来你需要使用集合。

我们的邻里友好型Lisp专家指出

他还提供了以下片段:

(defun merge-lists (list-a list-b sort-fn test-fn)
    (sort (remove-duplicates (append list-a list-b) :test test-fn) sort-fn))

如果在合并列表之前对列表进行了排序,则可以同时合并、删除和排序列表。如果对它们进行了排序并且没有重复,那么merge/sort/duplicate remove函数就变得非常简单

事实上,最好更改insert函数,以便它执行排序插入以检查重复项。然后,您总是有没有重复的排序列表,合并它们是一件小事


同样,您可能更喜欢使用快速插入功能,但代价是以后对重复项进行排序/删除。

如果在删除重复项之前应用排序,删除重复项功能是否会运行得更好?

正如Antti指出的,您可能希望利用删除重复项和排序,虽然我可能会对测试函数使用关键字(或可选参数): (定义合并列表(列表-1列表-2排序fn和键(测试#'eql)) ...) 或 (定义合并列表(列表-1列表-2排序fn&可选(测试#'eql)) …)


这样,您就不必指定测试函数(由REMOVE-DUPLICATES用于测试“这些被认为是重复的吗”),除非EQL不够好。

您可能想澄清“更好”的含义.你试过这个未经测试的代码段了吗?它成功了吗?我很想编辑我的答案,这样我们以后的几代人就不必担心代码段会破坏他们的Lisp 3000…我确实测试过它,它确实成功了。非常感谢你的回答。首先,
sort fn
是否与
相等
兼容?也就是说,
(sort fn a b)
=
NIL
(sort fn b a)
=
NIL
暗示
(等于a b)
=
T
?第二,你应该在
排序
之后合并
,以提高速度。第三,
sort fn
应该命名为
比较
或类似的名称。我知道有一种优雅的方法:)这不是优雅的-这是列表长度的平方和,而不是最长列表长度的线性。集合通常不排序。RKitson有一点。如果集合很容易使用,那么一开始就不必处理重复的集合。另一方面,要使用集合,需要将dsm使用的动物映射到整数。这听起来很平常。我带着一个类似的问题来到这里,映射到整数并不容易,可能不容易。根据HyperSpec,它不需要对列表进行排序。