【发布时间】:2019-02-13 23:22:25
【问题描述】:
对于一个爱好项目,我处理像
这样的 a-lists 列表((0 . 0) (0 . 1) (0 . 3) (0 . 4) (0 . 7) (0 . 8))
其中列表最多可以包含九个元素,并且 a-lists 仅包含从 0 到 9 的整数。我想将列表拆分为具有连续cdrs 的子单元。
(((0 . 0) (0 . 1)) ((0 . 3) (0 . 4)) ((0 . 7) (0 . 8)))
一个子单元可以只有一个元素,列表可以没有子单元,例如:
((0 . 0) (0 . 1) (0 . 2) (0 . 4)) 或
((0 . 0) (0 . 1) (0 . 2) (0 . 3) (0 . 4))
结果应该是:
(((0 . 0) (0 . 1)) ((0 . 3) (0 . 4)) ((0 . 7) (0 . 8)))
(((0 . 0) (0 . 1) (0 . 2)) ((0 . 4)))
(((0 . 0) (0 . 1) (0 . 2) (0 . 3) (0 . 4)))
使用iterate 我想出了一个两步法。首先,扫描列表,检查是否有子单元,返回间隙的位置。其次,使用我之前实现的函数split-at 拆分列表:
(defun split-at (count original-list)
(unless (or (null original-list) (minusp count)
(>= count (length original-list)))
(list (subseq original-list 0 count)
(subseq original-list count))))
(defun sub-units (units)
"Scan UNITS for sub-units."
(iter
(for (a . b) in units)
(for last-b previous b initially -1)
(for pos from 0)
(unless (= 1 (- b last-b))
(collecting pos))))
(defun split-sub-units (units)
"Splits UNITS into its sub-units."
(iter
(with pos = (or (sub-units units) (list 0)))
(for p in pos)
(for last-p previous p)
(for (head tail) first (split-at p units) then (split-at last-p tail))
(when head
(collect head into result))
(finally (return (nconc result (list tail))))))
是否可以将sub-units 和split-sub-units 这两个函数合并为一个?它对风格或效率有什么影响吗?
【问题讨论】:
标签: list common-lisp