用mapcar计算欧氏距离并应用

Gav*_*vin 0 lisp common-lisp

我正在尝试创建一个使用apply和mapcar来计算它的函数.

在使用第一个mapcar获取列表中pq的所有差异后,我陷入困境.如何对列表中的所有元素进行平方并将它们相加?

在此输入图像描述

(defun euclidean-distance-map (p q)
  ;; get a list of differences of p - q
  (mapcar #'- p q))
Run Code Online (Sandbox Code Playgroud)

sds*_*sds 7

高阶函数

如果你真的需要坚持HOF(reduce&mapcar),那么这里有几个选择:

(defun euclidean-distance-map (p q)
  (let ((d (mapcar #'- p q))) ; get a list of differences of p & q
    (sqrt (reduce #'+ (mapcar #'* d d)))))

(defun euclidean-distance-map (p q)
  (sqrt (reduce #'+ (mapcar (lambda (x) (* x x)) (mapcar #'- p q)))))

(defun euclidean-distance-map (p q)
  (sqrt (reduce #'+ (mapcar (lambda (x y)
                              (let ((d (- x y)))
                                (* d d)))
                            p q))))
Run Code Online (Sandbox Code Playgroud)

apply VS reduce

使用apply而不是reduce一个主意(因为call-arguments-limit和风格),但在这里你去:

(defun euclidean-distance-map (p q)
  (let ((d (mapcar #'- p q))) ; get a list of differences of p & q
    (sqrt (apply #'+ (mapcar #'* d d)))))

(defun euclidean-distance-map (p q)
  (sqrt (apply #'+ (mapcar (lambda (x) (* x x)) (mapcar #'- p q)))))

(defun euclidean-distance-map (p q)
  (sqrt (apply #'+ (mapcar (lambda (x y)
                             (let ((d (- x y)))
                               (* d d)))
                           p q))))
Run Code Online (Sandbox Code Playgroud)

记忆

如果没有众所周知的"足够智能的编译器",则mapcar分配立即丢弃的存储.然而,这可能不一定是现代世代GC的问题.

迭代

请注意,使用的迭代版本loop同样明确:

(defun euclidean-distance-map (p q)
  (sqrt (loop for x in p
          and y in q
          for d = (- x y)
          sum (* d d))))
Run Code Online (Sandbox Code Playgroud)

Lisp是一种多范式语言,您不必强迫自己进入特定的框架.