2015-04-19 2 views
0

Я пытаюсь найти расстояние между двумя точками в 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 на последнем элементе, возвращаемом помощником?

+1

Это обычно называть '' helper' из helper'. Или вы получаете '(sqrt (+ (sqrt (+ (sqrt (+ (sqrt 0) (expt ...)) (expt ...)) (expt ...)))' – Sylwester

ответ

4

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 часть, а весь цикл сумма обрабатывается вашим рекурсивной helper.

+0

Вот что я получаю копирование и вставка – m0meni

1

Вам не нужна рекурсия для этого.

(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)) 

Runnable образец: http://eval.ironscheme.net/?id=145

+0

Спасибо! Это первая программа, которую я написал в схеме, поэтому я не знал, что у меня есть доступ ко всем этим вещам. – m0meni

Смежные вопросы