# Lisp反转元素的所有连续序列

Mocktheduck

`````` Ex:
(reverseC '( 1 2 ( 4 5 ) 5 ) ) => ( 2 1 ( 5 4 ) 5 )
(reverseC '(1 4 2 (3 4) 9 6 (7 8)))) => (2 4 1 (4 3) 6 9 (8 7))
``````

``````(defun reverse-list ( lista )
(if (eql lista () )
()
(append (reverse-list (cdr lista )) (list ( car lista)))
)
)
``````

``````(defun reverse-more (L)
(if (eql L nil)
nil
(let ( el (car L)) (aux (cdr L)))
(if (eql (listp el) nil)
...No idea on the rest of the code ...
``````

``````(defun reverse-consecutive (list &optional acc)
(etypecase list

;; BASE CASE
;; return accumulated list
(null acc)

;; GENERAL CASE
(cons (destructuring-bind (head . tail) list
(list
;;
;; - stop accumulating values
;; - reverse HEAD recursively (LH)
;; - reverse TAIL recursively (LT)
;;
;; Result is `(,@ACC ,LH ,@LT)
;;
(nconc acc
(reverse-consecutive tail)))

;; HEAD is not a list
;;
;; - recurse for the result on TAIL with HEAD
;;   in front of ACC
;;
(t (reverse-consecutive tail (cons head acc))))))))
``````

### 例子

``````(reverse-consecutive '(1 2 (3 4) 5 6 (7 8)))
=> (2 1 (4 3) 6 5 (8 7))

(mapcar #'reverse-consecutive
'((1 3 (8 3) 2 )
(1 4 2 (3 4) 9 6 (7 8))
(1 2 (4 5) 5)))

=> ((3 1 (3 8) 2)
(2 4 1 (4 3) 6 9 (8 7))
(2 1 (5 4) 5))
``````

### 备注

@ Melye77该`destructuring-bind`表达式与`[Head|Tail] = List`Prolog中的功能相同我本可以写这个

``````(let ((head (first list))
(tail (rest list)))
...)
``````

``````(if acc
(if (listp (first list))
(nconc ...)
(reverse-consecutive ...))
acc)
``````

...但是我认为这对初学者来说不太清楚，也不是一件好事。相反，我认为，介绍（尤其是对于初学者而言）介绍所有可用的构造都是有用的。例如，实际上不建议过度使用递归函数：对于序列而言，有很多现有的迭代构造不依赖于尾部调用优化的可用性（尽管通常可以通过适当的声明来使用，但不能保证实现这些优化） 。

### 迭代版

``````(defun reverse-consecutive (list)
(let (stack result)
(dolist (e list (nreverse result))
(typecase e
(list
(dolist (s stack)
(push s result))
(push (reverse e) result)
(setf stack nil))
(t (push e stack))))))
``````

0 条评论