【问题标题】:Adding two lists添加两个列表
【发布时间】:2014-05-26 21:56:49
【问题描述】:

我想添加两个列表:(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)
)

我怎样才能创建一个类似的函数来减去列表?

【问题讨论】:

  • 您一直在问一些相对基本的 Lisp 问题,所有这些问题都与处理数字列表的主题相同。坐下来学习一些 Lisp 教程或一本好的 Lisp 教科书可能会更好。在这个问题和您之前的两个问题之间,您似乎要求我们为您完成大部分项目。即使浏览 HyperSpec 中的 14.1.2 Conses as Lists14.2 The Conses Dictionary 也会有所帮助。
  • 我已经设法在不使用 mapcar 的情况下创建了一个减法函数。 @Joshua,我研究了你的解决方案并用它们来解决我的问题。是的,我最初问过我在做一个项目时遇到的问题,但我已经搞定了。再次感谢您的帮助。
  • @BogdanMolinger 你为什么要避免mapcar?如果您使用mapcar,那么您尝试执行的任务似乎很简单。例如,(defun sum (x y) (digits->number (mapcar '+ x y)))(defun difference (x y) (digits->number (mapcar '- x y)))(其中 digits->number 定义在您的其他问题的 my answer 中)。
  • @JoshuaTaylor 我认为 mapcar 可以很好地添加两个列表,我可以在结果上应用 decompose 函数,但是很难使用 mapcar 进行减法,因为我可能会得到类似的东西(-10 5 -16 8 9) 考虑到借来的进位,这将更难标准化。
  • 随身携带有什么问题?使用我提供的代码,(digits->number '(-5 2)) 产生 15(即 -5 + 20),(digits->number '(-10 5 -16 8 9)) 产生 96440(我认为这是正确的)。由于您实际上只是在评估多项式,因此它似乎应该起作用。例如,(digits->number (mapcar '- '(2 8 4) '(5 5 5)))(- 482 555) 都产生 -73

标签: lisp common-lisp


【解决方案1】:

如果你被允许使用标准函数,那么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)))

【讨论】:

    【解决方案2】:

    多项式算术

    这似乎是对您之前的问题Decompose a list of numbers into digits 的跟进。在那里,你有一个数字列表,它们是

    形式的多项式的 ai

    i=0… 10iai

    列表中的 n 个数字是 a0 到 an-1 的值,之后的所有内容都假定为为零。您要求一种方法来规范化值,使每个 ai 都在 [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) →(number->digits (digits->number …)) (7 9 8)

    区别很简单

    (8-9) + (7-1)×10 + (3-5)×100 →(mapcar '- x y) (-1 6 -2) →?? ? ???

    我们这里没有适当的标准化程序。上一个问题中提供的那个在这里不起作用。但是,就系数而言,数字列表仍然是正确的,digits->number 过程会产生正确的值 -141。

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

    (defun sum (x y)
      (mapcar '+ x y))
    
    (defun difference (x y)
      (mapcar '- x y))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-18
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      • 2011-08-26
      • 1970-01-01
      相关资源
      最近更新 更多