我只想反转连续序列,而不是原始列表中的所有元素。
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))
我当时正在考虑将其拆分为2个功能:一个功能反转一个简单列表(1 2 3)->(3 2 1)和一个功能(主要)来确定连续序列,从中创建一个列表,然后对该列表,然后重新制作整个反向列表。
(defun reverse-list ( lista )
(if (eql lista () )
()
(append (reverse-list (cdr lista )) (list ( car lista)))
)
)
这是反向功能,但我不知道该如何做另一项。我是Lisp的新手,我来自Prolog,所以这是一个非常大的景观更改。任何想法都欢迎。
(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
(typecase head
(list
;; HEAD is a list:
;;
;; - stop accumulating values
;; - reverse HEAD recursively (LH)
;; - reverse TAIL recursively (LT)
;;
;; Result is `(,@ACC ,LH ,@LT)
;;
(nconc acc
(list (reverse-consecutive head))
(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)))
...)
同样,我更倾向于尽可能使用(e)typecase
泛型cond
表达式,因为我认为它更精确。
我可以写:
(if acc
(if (listp (first list))
(nconc ...)
(reverse-consecutive ...))
acc)
...但是我认为这对初学者来说不太清楚,也不是一件好事。相反,我认为,介绍(尤其是对于初学者而言)介绍所有可用的构造都是有用的。例如,实际上不建议过度使用递归函数:对于序列而言,有很多现有的迭代构造不依赖于尾部调用优化的可用性(尽管通常可以通过适当的声明来使用,但不能保证实现这些优化) 。
这是使用标准reverse
和nreverse
功能的迭代版本。与上述方法相反,内部列表被简单地反转(仅在深度的第一级别检测到连续的块):
(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))))))
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句