的
通过使用
map
仅限家庭功能
</强>
在我看来,这是非常lispy(也许是一个解决方案
loop
-haters):
(defun 1st-conses (l)
(mapcar #’(lambda (x) (cons (car l) x)) l))
(mapcan #’1st-conses (maplist #’identity ‘(1 3 5 7 9))
;; ((1 . 1) (1 . 3) (1 . 5) (1 . 7) (1 . 9) (3 . 3) (3 . 5) (3 . 7) (3 . 9)
;; (5 . 5) (5 . 7) (5 . 9) (7 . 7) (7 . 9) (9 . 9))
</code>
的
仅通过递归
</强>
和尾部调用递归解决方案
loop
-haters:
(defun 1st-conses (l)
(labels ((.1st-conses (l fst acc)
(cond ((null l) (nreverse acc))
(t (.1st-conses (cdr l) fst (cons (cons fst (car l))
acc))))))
(.1st-conses l (car l) ‘())))
(defun combine-down (l &optional (acc ‘()))
(cond ((null l) acc)
(t (pairing-down (cdr l) (nconc acc (1st-conses l))))))
(combine-down ‘(1 3 5 7 9))
;; ((1 . 1) (1 . 3) (1 . 5) (1 . 7) (1 . 9) (3 . 3) (3 . 5) (3 . 7) (3 . 9)
;; (5 . 5) (5 . 7) (5 . 9) (7 . 7) (7 . 9) (9 . 9))
</code>
的
小
loop
功能
</强>
这三个函数的融合版本在其他答案中给出:
(defun tails (l)
(loop for x on l collect x))
(defun 1st-conses (l)
(loop for x in l collect (cons (car l) x)))
(loop for l in (tails ‘(1 3 5 7 9))
nconc (1st-conses l))
</code>
的
具有小功能的更通用解决方案
</强>
结合这三个功能中的任何一个 - 每个功能都带有一个
map
-version,a
loop
-version和尾调用递归版本。 - 所以你可以选择创建一个
纯粹
map
解
纯粹
loop
解决方案或
纯粹的递归解决方案。
或者您
故意混淆他们;)
功能是:
;;;;;;;;;;;;;;;;;;;;
;; function collecting all cdr
s of a list:
;; (tails ‘(a b c))
;; ;; returns: ((A B C) (B C) (C))
;;;;;;;;;;;;;;;;;;;;
;; with map
s
(defun tails (l)
(maplist #’identity l))
;; with loop
(defun tails (l)
(loop for x on l collect x))
;; tail-call-recursion
(defun tails (l &optional (acc ‘()))
(cond ((null l) (nreverse acc))
(t (tails (cdr l) (cons l acc)))))
;;;;;;;;;;;;;;;;;;;;
;; function collecting car
of a list cons
ed with each list element
;; (1st-conses ‘(a b c))
;; ;; returns: ((A . A) (A . B) (A . C))
;;;;;;;;;;;;;;;;;;;;
;; with map
s
(defun 1st-conses (l)
(mapcar #’(lambda (x) (cons (car l) x)) l))
;; with loop
(defun 1st-conses (l)
(loop for x in l collect (cons (car l) x)))
;; tail-call-recursion
(defun 1st-conses (l)
(labels ((.1st-conses (l fst acc)
(cond ((null l) (nreverse acc))
(t (.1st-conses (cdr l) fst (cons (cons fst (car l))
acc))))))
(.1st-conses l (car l) ‘())))
;;;;;;;;;;;;;;;;;;;;
;; applying the second function on the first functions’ results
;; (combine-down ‘(a b c))
;; ;; returning: ((A . A) (A . B) (A . C) (B . B) (B . C) (C . C))
;;;;;;;;;;;;;;;;;;;;
;; with map
s
(defun combine-down (l)
(mapcan #’1st-conses (tails l)))
;; with loop
(defun combine-down (l)
(loop for x in (tails l)
nconc (1st-conses x)))
;; with tail-call-recursion
(defun combine-down (l)
(labels ((.combine-down (l acc)
(cond ((null l) acc)
(t (.combine-down (cdr l)
(nconc acc
(1st-conses (car l))))))))
(.combine-down (tails l) ‘())))
</code>
然后:
(combine-down ‘(1 3 5 7 9))
;; ((1 . 1) (1 . 3) (1 . 5) (1 . 7) (1 . 9) (3 . 3) (3 . 5) (3 . 7) (3 . 9)
;; (5 . 5) (5 . 7) (5 . 9) (7 . 7) (7 . 9) (9 . 9))
</code>
的
势在必行
</强>
为了好玩,我尽可能地翻译了命令式cpp代码 -
因为作为一种真正的多范式语言…:
(let ((arr ‘(1 3 5 7 9))
(res ‘()))
(loop for i from 0 below 5 by 1
do (loop for j from i below 5 by 1
do (setq res (cons (cons (elt arr i)
(elt arr j))
res))))
(nreverse res))
</code>
它正确返回:
((1 . 1) (1 . 3) (1 . 5) (1 . 7) (1 . 9) (3 . 3) (3 . 5) (3 . 7) (3 . 9)
(5 . 5) (5 . 7) (5 . 9) (7 . 7) (7 . 9) (9 . 9))
</code>