【问题标题】:LISP: multi-level recursive reverse functionLISP:多级递归反向函数
【发布时间】:2010-11-28 04:59:16
【问题描述】:

如何反转列表以使每个子列表也反转?这是我目前所拥有的:

(defun REV (L)
  (cond
    ((null L) nil)
    ((listp L)
     (append
      (REV (cdr L))
      (list (car L))))
    (t
     (append
      (REV (cdr L)) 
      (list (car L))))))

【问题讨论】:

    标签: list recursion lisp


    【解决方案1】:

    听起来像是一个家庭作业问题:)

    看起来您是从编写常规反向代码开始的。我给你一个提示:第二个条件(listp L)不太正确(它总是正确的)。你想检查其他东西是否是一个列表。

    【讨论】:

      【解决方案2】:

      您在正确的轨道上,但您的最后两个条件具有相同的动作,这应该表明其中一个条件没有做它应该做的事情。事实上,第二个条件listp 是不正确的,因为当它是一个列表时,您需要附加该列表的反向而不是未修改的列表。一个可能的解决方案:

      (defun my-reverse (l)
        (cond ((null l) nil)
              ((listp (car l)) (append (my-reverse (cdr l)) 
                                       (list (my-reverse (car l)))))
              (t
                (append (my-reverse (cdr l)) 
                        (list (car l))))))
      
      >  (my-reverse '((1 2 3) (4 5 6)))
      ((6 5 4) (3 2 1))
      

      如您所见,唯一的区别是您测试第一个元素是否为列表,如果是,则在追加之前反转第一个元素。

      【讨论】:

      • 短一点: (defun my-reverse (l) (if (null l) nil (append (my-reverse (cdr l)) (list (if (listp (car l))) my-reverse (car l)) (car l))))))
      【解决方案3】:

      我会这样写:

      (defun reverse-all (list)
        (loop
           with result = nil
           for element in list
           if (listp element)
           do (push (reverse-all element) result)
           else do (push element result)
           finally (return result)))
      

      【讨论】:

        【解决方案4】:

        dmitry_vk 的回答(在大多数 lisps 中可能比在前面的示例中使用 append 更快)以更 lispish 的方式:

        (defun reverse-all (list)
          (let ((result nil))
            (dolist (element list result)
              (if (listp element)
                  (push (reverse-all element) result)
                  (push element result)))))
        

        甚至:

        (defun reverse-all (list)
          (let ((result nil))
            (dolist (element list result)
              (push
                (if (listp element) (reverse-all element) element)
                  result))))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-01
          • 1970-01-01
          • 2020-09-26
          • 1970-01-01
          • 2016-01-22
          相关资源
          最近更新 更多