【问题标题】:Scheme operation performed recursively instead of only once方案操作递归执行,而不是只执行一次
【发布时间】:2015-04-19 18:26:12
【问题描述】:

我正在尝试找出 3D 空间中两点之间的距离:

这是我的代码:

(define (helper p1 p2)
    (if (null? p1)
        0
        (+ (distTo3D (cdr p1) (cdr p2))
           (expt (- (car p1) (car p2)) 2))))

(define (distTo3D p1 p2)
    (sqrt (helper p1 p2)))

我认为定义一个助手可能会使sqrt 仅在助手函数末尾返回的元素上被调用。但是,如果有这样的电话:

(distTo3D '(1 1 1) '(2 2 2))

它返回了错误的答案。经过一段时间的实验,我看到它返回了sqrt(sqrt(1) + sqrt(2)),就好像 sqrt 是递归语句本身的一部分一样。

如何更改我的代码,使其仅在助手返回的最后一个元素上调用 sqrt?

【问题讨论】:

  • 通常从helper 调用helper。否则你会得到(sqrt (+ (sqrt (+ (sqrt (+ (sqrt 0) (expt ...)) (expt ...)) (expt ...)))

标签: functional-programming scheme


【解决方案1】:

helper 应该调用自己,而不是原来的函数:

(define (helper p1 p2)
    (if (null? p1)
        0
        (+ (helper (cdr p1) (cdr p2))
           (expt (- (car p1) (car p2)) 2))))

每次您返回原始函数(sqrt 所在的位置)时,都会添加另一个不合适的 sqrt。如果你看距离的定义,它是:

sqrt( sum( (x_i - y_i)^2 from 0 to n ) )

distTo3D 正在执行 sqrt 部分,整个 sum 循环由您的递归 helper 处理。

【讨论】:

  • 复制粘贴就是这样
【解决方案2】:

你不需要为此递归。

(define (helper p1 p2)
    (expt (- p1 p2) 2))

(define (distTo3D p1 p2)
    (inexact (sqrt (apply + (map helper p1 p2)))))

(distTo3D '(1 1 1) '(2 2 2))

可运行示例:http://eval.ironscheme.net/?id=145

【讨论】:

  • 谢谢!这是我用 scheme 编写的第一个程序,所以我真的不知道我可以访问所有这些东西。
猜你喜欢
  • 2018-09-26
  • 2021-02-18
  • 2012-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多