我需要编写一个lisp函数,将x添加到列表的第n项。例如,(add 5 2 '(3 1 4 6 7))
会返回(3 6 4 6 7)
。
选择nthitem是
(defun nthitem (n list)
(cond ((equal n 1) (car list))
(t (nthitem (-n 1) (cdr list)))))
并将x添加到列表中:
(defun addto (x list)
(cond ((null list) nil)
(t (cons (+ x (car list))
(addto x (cdr list))))))
但我无法将这两者结合在一起。
答案 0 :(得分:1)
我们没有足够使用nreconc
。这是基于do
和reconc
的解决方案。我们的想法是沿着列表中的元素以相反的顺序累积元素,直到找到需要替换的元素的位置。然后你把这些位粘在一起。也就是说,你反转你一直在积累的列表,然后将它附加到从新元素和尾部构建的列表中。
(defun add (number index list)
(do ((head '() (list* (first tail) head))
(tail list (rest tail))
(index index (1- index)))
((zerop index)
(nreconc head (list* (+ number (first tail))
(rest tail))))))
CL-USER> (add 5 2 '(3 1 4 6 7))
(3 1 9 6 7)
值得看看这些价值观随着时间的推移而变化。让我们考虑一个包含更多数字的示例,并在每次迭代中查看head
,tail
和index
的值:
CL-USER> (add 90 5 '(0 1 2 3 4 5 6 7 8 9))
(0 1 2 3 4 95 6 7 8 9)
head: ()
tail: (0 1 2 3 4 5 6 7 8 9)
index: 5
head: (0)
tail: (1 2 3 4 5 6 7 8 9)
index: 4
head: (1 0)
tail: (2 3 4 5 6 7 8 9)
index: 3
head: (2 1 0)
tail: (3 4 5 6 7 8 9)
index: 2
head: (3 2 1 0)
tail: (4 5 6 7 8 9)
index: 1
head: (4 3 2 1 0)
tail: (5 6 7 8 9)
index: 0
我们到达0
后,我们可以通过将number
添加到(car tail)
并将其与{{1}放在一起来获得最终结果的 rest ,即
(cdr tail)
产生
(list* (+ (car tail) number) (cdr tail)
然后使用nreconc
获取(95 6 7 8 9)
和(4 3 2 1 0)
并获取(95 6 7 8 9)
,即
(0 1 2 3 4 95 6 7 8 9)
现在,如果由于某种原因你不能使用(nreconc (list 4 3 2 1 0) '(95 6 7 8 9))
;=> (0 1 2 3 4 95 6 7 8 9)
,例如,这是一个家庭作业,那么这个跟踪应该仍然给你足够的信息来用累加器写一个直接的递归版本。不过,无论如何,您仍然需要do
(或reverse
)列表,以及nreverse
(或append
)一些列表(或者,nconc
或revappend
)。
答案 1 :(得分:0)
您遇到了重大的格式问题,而且某些地方的运营商之间缺乏空间。请务必使用与Emacs或Kate进行括号匹配的编辑器。
只是为了向您展示如何在不更改addto
功能
(defun addto (x n list)
(cond ((null list) nil)
(t (cons (+ x (car list))
(addto x (- n 1) (cdr list))))))
因此除了基本情况之外,您的代码应该有两种情况。一个(= n 1)
,因为你从1开始计数而不是0,这是你今天的默认情况,另一个不添加car
,只需在cdr
进行相同的递归时进行复制。祝你好运
答案 2 :(得分:0)
使用setnth
(setq a (list 3 1 4 6 7))
(defun add-number-to-nth-element (arg liste element)
"Add ARG, a number, to nth ELEMENT of LISTE. "
(setnth element liste (+ arg (nth element liste)))
liste)
(add-number-to-nth-element 5 a 1)
;; ==> (3 6 4 6 7)
;; ==> (3 11 4 6 7)
;; ==> (3 16 4 6 7)
;; ==> (3 21 4 6 7)
;; ==> (3 26 4 6 7)
;;计数元素从0开始
答案 3 :(得分:0)
您需要的只是nth
和setf
:
emacs -Q
,然后评估以下内容:
(defun add-to-nth (x n ys)
(when ys (setf (nth n ys) (+ x (nth n ys)))))
(setq foobar '(1 2 3 4 5))
(add-to-nth 42 1 foobar)
C-h v foobar ; => (1 44 3 4 5)