【问题标题】:Why does this sorting algorithm do what it is supposed to? [Lisp]为什么这个排序算法会做它应该做的事情? [口齿不清]
【发布时间】:2015-08-13 06:10:56
【问题描述】:

我正在研究旧考试,为自己的考试做准备,教授很友善,还为我们提供了解决方案,现在我想知道为什么一个函数会做它应该做的事情。

(defun sortulists (L)
  (mapcar (lambda (uliste)
            (sort uliste (lambda (x1 x2)
                           (or (symbolp x2)
                               (and (numberp x1) (numberp x2)
                                    (< x1 x2))))))
          L))

它应该获取一个列表L,其中包含可能包含数字和原子的未排序子列表,并首先对其数字进行排序,然后将符号放在末尾。

当像这样调用(sortulists '((A 9 b h 2) (1 m n 9 8) (5 a 7))) 时,它会返回((2 9 H B A) (1 8 9 N M) (5 7 A))

有什么帮助吗?

编辑:固定缩进

【问题讨论】:

  • 你不明白的部分有什么精确的吗?
  • 我的问题是理解(or symbolp x2) (and (numberp x1) (numberp x2) (&lt; x1 x2)))))) 部分。我知道&lt; x1 x2 是实际排序,但我对orand 感到困惑。是符号还是排序后的数字?
  • 请注意,此谓词导致符号的顺序不可预测。此外,您的示例调用将文字列表传递给sortulists,这会将内部文字列表传递给sort, which is allowed to destructively modify the sequence。这意味着undefined behavior

标签: sorting lisp common-lisp


【解决方案1】:

sort 函数的谓词表明,一旦序列被排序,哪些测试必须为真。排序是如何完成的没有定义。

如果您对这里使用的andor 感到困惑,我建议您阅读Common Lisp: A Gentle Introduction to Symbolic Computation条件 一章。它展示了如何交换cond、嵌套ifs 以及andor 的组合,并提供练习(及其解决方案)。

简而言之,要么右边必须有一个符号,要么如果都是数字,则必须按大小排序。

【讨论】:

  • 关于排序功能和测试的部分真的很有帮助。谢谢。
【解决方案2】:
(or
    ; if x2 is a symbol, then x1 is smaller, whatever x1 is
    (symbolp x2)

    ; if both are numbers, then return t if x1 is smaller than x2
    (and (numberp x1) (numberp x2)
         (< x1 x2)))

所以数字是排序的并且在前面。符号位于末尾,但未排序。

【讨论】:

    【解决方案3】:

    所以说的很明显:

    (defun sortulists (L)
      (mapcar (lambda (uliste)
                (sort uliste (lambda (x1 x2)
                               (or (symbolp x2)
                                   (and (numberp x1) (numberp x2)
                                        (< x1 x2))))))
              L))
    

    mapcar 只是列出了将匿名函数应用于每个元素的列表。所以只关注一个元素'(A 9 b h 2) 你可以这样做:

    ;; same as the anonymous lambda, but named so we can test it a little
    (defun my< (x1 x2)
      (or (symbolp x2)
          (and (numberp x1) (numberp x2)
               (< x1 x2))))
    
    (sort '(A  9  b  h  2) #'my<) ; ==> (2 9 B H A)
    
    (my< 2 'a)                    ; ==> T 
    (my< 2 3)                     ; ==> T
    (my< 3 3)                     ; ==> NIL
    (my< 'a 2)                    ; ==> NIL
    (my< 'a 'b)                   ; ==> T
    (my< 'b 'a)                   ; ==> T
    

    如果x2 是一个符号,则查看my&lt; x1 小于x2。如果x1 都是数字并且x1 在算术上小于x2,则x1 也更小。对于其他一切x1 等于或大于x2

    如果您在参数列表中混合一些符号,您可能会发现您获取符号的顺序与原始列表不同。原因是两个符号比较会变成t,所以'a小于'b'b小于'a。我们在结果中保持符号顺序的版本如下所示:

    (stable-sort '(A  9  b  h  2)
          (lambda (x1 x2)
            (and (numberp x1) 
                 (or (not (numberp x2))
                     (< x1 x2)))))
    ; ==> (2 9 A B H)
    

    注意我使用了stable-sort 函数,因为sort 不能保证稳定。稳定意味着相等的对象与源保持相同的顺序。

    【讨论】:

      猜你喜欢
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-19
      • 1970-01-01
      • 2011-09-28
      相关资源
      最近更新 更多