我的向量定义为:
(x1, x2, …, xn) and (y1, y2, …yn)
我试图这样计算它们:
sqrt((x1-y1)*(x1-y1) + (x2-y2)*(x2-y2) + … + (xn-yn)*(xn-yn))
我在使用超过 2 个元素的向量时遇到问题。我一直在尝试使用 for-each 循环,但我无法让递归正常工作。
此外,我可以得到除最终数字的 sqrt 之外的所有内容。我试图将最终数字定义为一个变量,然后取该变量的sqrt,但我的解释器说了一些关于"在表达式中不允许定义......"的内容。
到目前为止,我的工作代码:
(define vectordistance
(lambda (v1 v2)
(if
(null? v1) 0
(+
(*
(- (car v1) (car v2))
(- (car v1) (car v2))
)
(vectordistance (cdr v1) (cdr v2))
)
)
))
首先,你使用的是列表 - vector
在 Scheme 中是不同的野兽。解决方案的关键点是您必须迭代列表,并以某种方式累积答案,直到没有更多元素。此外,辅助函数在这里也很有用,因为首先我们必须累加加法,并且只在最后取平方根。假设两个列表的长度相同:
; this is the same as yours, but better formatted
(define (helper v1 v2)
(if (null? v1)
0
(+ (* (- (car v1) (car v2))
(- (car v1) (car v2)))
(helper (cdr v1) (cdr v2)))))
; call the above as a helper and take the square root of the result
(define (vectordistance v1 v2)
(sqrt (helper v1 v2)))
作为奖励(由 Chris 建议),您可以使用fold
过程以更惯用的方式编写helper
。检查你的解释器的文档,它可能被称为foldl
或fold-left
或简称fold
,但这就是你使用它的方式 - 这个想法是避免使用显式递归并赞成使用高阶过程:
(define (square x)
(* x x))
(define (helper v1 v2)
(foldl (lambda (e1 e2 r)
(+ (square (- e1 e2)) r))
0
v1 v2))