我的任务是写一个递归的欧氏距离。我一直在谷歌搜索,但找不到任何样本。我理解欧几里德距离的功能,并且没有问题以迭代方式写入,如下所示。是否有人可以告诉我如何启动递归函数?要求与迭代版本相同。谢谢。
{% 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 %}
答案 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))))))
使用递归版本,我认为p
和q
是两个数学向量,因此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。我没有检查p
和q
是否是原子,但它们可以被视为一维向量。从预期提供数值的函数返回NIL
并不是一个好主意。