添加两个列表

时间:2014-05-26 21:56:50

标签: lisp common-lisp

我想添加两个列表:(1 2 3)和(5 3 4)应该产生(6 5 7)。
该函数应该在相应的位置添加元素,所以即使我有(9 1 2)+(5 2 6),它也应该屈服(14 3 8)。
  我的功能

(defun add(l r)
    (setf return-value '())
        (loop for i from 0 to (- (length l) 1)
            do (setf return-value (cons (+(nth i l)(nth i r)) return-value))
        )
    (reverse return-value)
)

我怎样才能创建一个可以减去列表的simmilar函数?

2 个答案:

答案 0 :(得分:3)

如果您被允许使用标准功能,那么mapcar就是您的朋友:

(mapcar #'+ '(1 2 3) (9 7 5))
==> (10 9 8)

同样适用于-

您的功能受到二次性能的影响 - 您不应该使用nth。 您还应该将return-valuelet绑定。 您还应该使用nreverse instead of reverse,因为无论如何您正在构建一个新的列表。

编写函数的惯用方法是

(defun addl (l r)
  (loop for x in l and y in r collect (+ x y)))

答案 1 :(得分:0)

多项式算术

这似乎是您上一个问题Decompose a list of numbers into digits的后续跟进。在那里,你有一个数字列表的数字,它们是形式的多项式的 i

Σ i = 0 ... 10 i a i

其中列表中的 n 数字是 0 n-1 的值,之后的所有内容都被假定为为零。你想要一种方法来规范化这些值,使得每个 i 都在[0,9]的范围内。该问题My answer显示了一些方法。

现在,一旦您将数字视为此形式的多项式,就可以很容易地看到,您可以简单地对系数进行分段加法和减法,以获得总和或差的系数(如果尚未归一化)。例如,

378 = 8 + 7×10 + 3×100→(8 7 3)
519 = 9 + 1×10 + 5×100→(9 1 5)

总和就是

(8 + 9)+(7 + 1)×10 +(3 + 5)×100→ (mapcar '+ x y) (17 8 8)→ {{1} } (7 9 8)

区别仅在于

(8-9)+(7-1)×10 +(3-5)×100→ (number->digits (digits->number …)) ( - 1 -2 -2)→ ?? ? ???

我们这里没有的是适当的规范化程序。上一个问题中提供的那个在这里不起作用。但是,数字列表仍然是正确的,只要系数为,并且(mapcar '- x y)过程产生正确的值-141。

因此,虽然您需要重新考虑显示负数的数字列表意味着什么,但您可以使用以下内容在列表中执行正确的加法和减法类型,只要两个列表都具有相同的长度。如果它们的长度不同,则需要用零填充较短的长度。支持此类操作的digits->number的重新实现在这里可能很有用。

mapcar