我通宵写了这个函数,它接受一个字符串列表,并将其转换为一个递归嵌套的值集合。我尝试使用pushnew,这样现有的字符串就不会被复制,但我必须创建自己的重复测试,因为我不能让pushnew来做这件事。
显然,有一种方法可以使用递归,但我不能让它工作,因为我不能让pushnew的目标部分正确调用。
我终于用了一种愚蠢的方式,但是什么是聪明的方式呢?
(defvar vocab '())
(defun place-down ( a b &optional c d e f g)
(unless (assoc a vocab :test #'equal)
(pushnew (cons a '()) vocab :test #'equal))
(unless (assoc b (cdr(assoc a vocab :test #'equal)):test #'equal)
(pushnew (cons b '()) (cdr(assoc a vocab :test #'equal :test #'equal))))
(when c
(unless (assoc c (cdr(assoc b (cdr(assoc a vocab :test #'equal :test #'equal
)):test #'equal)):test #'equal)
(pushnew (cons c '()) (cdr(assoc b (cdr(assoc a vocab :test #'equal
:test #'equal)):test #'equal)))))
(when d
(unless (assoc d (cdr(assoc c (cdr(assoc b (cdr(assoc a vocab :test #'equal
:test #'equal)):test #'equal)):test #'equal)):test #'equal)
(pushnew (cons d '()) (cdr(assoc c (cdr(assoc b (cdr(assoc a vocab :test
#'equal :test #'equal)):test #'equal)):test #'equal)))))
(when e
(unless (assoc e (cdr(assoc d (cdr(assoc c (cdr(assoc b (cdr(assoc a vocab
:test #'equal :test #'equal)) :test #'equal)):test #'equal)):test #'equal)):test #'equal)
(pushnew (cons e '()) (cdr(assoc d (cdr(assoc c(cdr(assoc b (cdr(assoc a vocab
:test #'equal :test #'equal)) :test #'equal)):test #'equal)):test #'equal)))))
(when f
(unless (assoc f (cdr(assoc e (cdr(assoc d(cdr(assoc c(cdr(assoc b (cdr(assoc a vocab
:test #'equal :test #'equal)) :test #'equal)):test #'equal)):test #'equal)):test #'equal))
:test #'equal)
(pushnew (cons f '()) (cdr(assoc e (cdr(assoc d(cdr(assoc c(cdr(assoc b (cdr(assoc a vocab
:test #'equal :test #'equal)) :test #'equal)):test #'equal)):test #'equal)):test #'equal)))))
(when g
(unless (assoc g (cdr(assoc f (cdr(assoc e(cdr(assoc d(cdr(assoc c(cdr(assoc b (cdr(assoc a vocab
:test #'equal :test #'equal)) :test #'equal)):test #'equal)):test #'equal)):test #'equal))
:test #'equal)):test #'equal)
(pushnew (cons g '()) (cdr(assoc f (cdr(assoc e(cdr(assoc d(cdr(assoc c(cdr(assoc b (cdr(assoc a vocab
:test #'equal :test #'equal)) :test #'equal)):test #'equal)):test #'equal)):test #'equal)):test #'equal)))))) 在回复中,我写道:
*(place-down "this" "is" "it" "the" "life" "we" "live")
* vocab
=> (("this" ("is" ("it" ("the" ("life" ("we" ("live"))))))))发布于 2018-02-19 21:52:33
这个例子看起来像是REDUCE可以解决的问题。
(defun place-down (&rest strings)
(reduce (lambda (string accumulator)
(if accumulator
(list string accumulator)
(list string)))
strings
:initial-value nil
:from-end t))带有显式:initial-value参数的REDUCE是以最统一的方式调用给定的reducing函数的情况;否则,可以使用零个或两个参数调用该函数,如果列表只有一个元素,则甚至根本不能调用该函数(谢谢@:initial-value)。如果累加器是NIL,我们就丢弃它。测试:
(place-down "this" "is" "it" "the" "life" "we" "live")
=> ("this" ("is" ("it" ("the" ("life" ("we" ("live")))))))
(place-down "this" "is" "it")
=> ("this" ("is" ("it")))
(place-down "this")
=> ("this")
(place-down)
=> NIL:from-end t参数使操作成为右关联的。
发布于 2018-02-20 17:04:18
CL-USER 8 > (loop with result = nil
for l in (reverse '("this" "is" "it" "the" "life" "we" "live"))
do (setf result (list (cons l result)))
finally (return result))
(("this" ("is" ("it" ("the" ("life" ("we" ("live"))))))))或
CL-USER 9 > (let ((result nil)
(list '("this" "is" "it" "the" "life" "we" "live")))
(dolist (l (reverse list) result)
(setf result (list (cons l result)))))
(("this" ("is" ("it" ("the" ("life" ("we" ("live"))))))))https://stackoverflow.com/questions/48866514
复制相似问题