首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编写递归LISP函数,查找两个相同长度的数字列表的点乘积。

编写递归LISP函数,查找两个相同长度的数字列表的点乘积。
EN

Stack Overflow用户
提问于 2016-10-03 06:44:43
回答 3查看 2.1K关注 0票数 1

刚开始学习LISP,我正试图找出如何编写以下递归函数。

所以我应该

代码语言:javascript
复制
(DOT-PRODUCT '(1 2) '(3 4)))

产量应该是11

我写了以下文章

代码语言:javascript
复制
(defun DOT-PRODUCT (a b)
  (if (or (null a) (null b))
      0
      (+ (* (first a) (first b))
         (DOT-PRODUCT (rest a) (rest b)))))

一切似乎都正常;然而,它仍然适用于不同长度的列表。我希望它只处理长度相同的数字列表。我应该在哪里添加返回“无效长度”的代码?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-03 06:51:09

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

代码语言:javascript
复制
(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,因此会立即生成一个错误。最后对计算结果进行了计算。

票数 4
EN

Stack Overflow用户

发布于 2016-10-13 04:59:45

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

代码语言:javascript
复制
(mapcar #'* X Y)

添加列表Z的元素:

代码语言:javascript
复制
(reduce #'+ Z)

加起来:点产品:

代码语言:javascript
复制
(reduce #'+ (mapcar #'* X Y))

reducemapcar是"MapReduce“概念的基础,它是这类事物的推广,包括点积、卷积积分以及各种传递和总结数据的方法。

票数 2
EN

Stack Overflow用户

发布于 2022-08-08 21:41:37

通过引入累加器变量并将标准递归转换为尾递归,可以提高效率。在本例中,我使用(labels)来定义递归:

代码语言:javascript
复制
(defun DOT-PRODUCT (a b)
  (labels ((dp (x y accum)
             (if (or (null x) (null y))
                 accum
                 (dp (rest x) (rest y) (+ accum (* (first x) (first y)))))))
    (if (= (length a) (length b))
        (dp a b 0)
        (error "Invalid length."))))
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39825848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档