递归的欧几里德距离

时间:2016-02-01 08:26:36

标签: recursion lisp

我的任务是写一个递归的欧氏距离。我一直在谷歌搜索,但找不到任何样本。我理解欧几里德距离的功能,并且没有问题以迭代方式写入,如下所示。是否有人可以告诉我如何启动递归函数?要求与迭代版本相同。谢谢。

{% if app.user %}
    {{ form_start(form) }}
        <input type="submit" class="form_submit_button" name="register_interest" value="Add to favourites"/>

    {{ form_end(form) }}
{% else %}
     <input type="button" class="form_submit_button" name="register_interest" value="Add to favourites"/>
{% endif %}

2 个答案:

答案 0 :(得分:3)

查看this Haskell thread,我认为您的任务更有可能计算n维向量的距离,即sqrt((x1-y1)^2 + ... + (xn-yn)^2)

在您的示例中没有迭代,您只需访问两个列表中的元素。换句话说:你假设P和Q包含2个元素,我认为问题是将它推广到N个元素。

此外,您正在进行许多无用的检查,以便返回nil而不是让错误发出信号。例如,如果列表不包含数字,则应该 not 返回nil。

我会像这样重写你的版本:

(defun euclidean-distance-it (p q)
  (destructuring-bind (x1 x2) p
    (destructuring-bind (y1 y2) q
      (sqrt (+ (expt (- x1 y1) 2)
               (expt (- x2 y2) 2))))))

使用递归版本,我认为pq是两个数学向量,因此p包含不同的坐标(p1, ..., pn),这与您的实现不同p {1}}包含所有 x q所有 y

因此,您必须为(pi - qi)^2(pi, qi)并行获取的元素p的每一个计算q,对中间值求和并取平方根。使用高阶函数,您甚至不需要使用递归。

我不会破坏递归的答案,但这是一个更高阶的函数版本:

(defun distance (p q) 
  (sqrt
    (reduce #'+ 
      (map 'list
        (lambda (px qx) (expt (- px qx) 2)) 
        p q))))

另一个loop

(defun distance (p q)
  (sqrt (loop for px in p
              for qx in q
              sum (expt (- px qx) 2))))

答案 1 :(得分:0)

如果输入是任何维度的两个向量(由列表表示),不仅是2或3,那么递归算法的唯一时间是明智的。在这种情况下,这将计算 square 距离:

(defun sq-euclid-distance (p q)
  (cond ((or (null p) (null q)) 0)
        (t (+ (expt (- (car p) (car q)) 2)
              (sq-euclid-distance (cdr p) (cdr q))))))

要从中获取SQRT,您需要将其作为辅助助手并使驱动程序计算平方根。

(defun euclid-distance (p q) (sqrt sq-euclid-distance p q))

PS。我没有检查pq是否是原子,但它们可以被视为一维向量。从预期提供数值的函数返回NIL并不是一个好主意。