编写一个递归LISP函数,找到两个相同长度的数字列表的点积

时间:2016-10-03 06:44:43

标签: recursion lisp common-lisp

刚开始学习LISP,我正在试图弄清楚如何编写以下递归函数。

我应该

(DOT-PRODUCT '(1 2) '(3 4)))

输出应为11

我写了以下内容

(defun DOT-PRODUCT (a b)
  (if (or (null a) (null b))
      0
      (+ (* (first a) (first b))
         (DOT-PRODUCT (rest a) (rest b)))))

一切似乎都有效;但是,它仍适用于不同长度的列表。我希望它只使用具有相同长度的数字列表。如果我们有这样的话,我应该在哪里添加返回“无效长度”的代码?

3 个答案:

答案 0 :(得分:3)

一种简单的方法是重写函数,以便使用条件形式cond检查不同的情况:

(defun dot-product (a b)
  (cond ((null a) (if (null b) 0 (error "invalid length")))
        ((null b) (error "invalid length"))
        (t (+ (* (first a) (first b))
              (dot-product (rest a) (rest b))))))

cond的第一个分支中,如果第一个参数是NIL,则第二个参数必须是NIL,否则会生成错误。在第二个分支中,我们已经知道a不是NIL,因此会立即生成错误。最后,计算结果。

答案 1 :(得分:0)

将列表X和Y的相应元素相乘:

(mapcar #'* X Y)

添加列表Z的元素:

(reduce #'+ Z)

放在一起:点积:

(reduce #'+ (mapcar #'* X Y))

答案 2 :(得分:0)

将列表X和Y的相应元素相乘:

(mapcar #'* X Y)

添加列表Z的元素:

(reduce #'+ Z)

放在一起:点积:

(reduce #'+ (mapcar #'* X Y))

reducemapcar是" MapReduce"的基础。概念,这是对这类事物的概括,包括点积,卷积积分以及无数种按摩和汇总数据的方式。