Почему это рекурсивное дополнение неправильно в Схеме? - PullRequest
3 голосов
/ 13 февраля 2012
#lang eopl

(define (vectorSum V b e)    ; b is starting index, and e is ending index
  (cond
    [ (eqv? b e) vector-ref V b]
    [ (> b e)
      (eopl:error 'vectorSum "starting index must be smaller than or equal to the end index")]
    [ else (+ (vector-ref V b) (vectorSum V (+ b 1) e))]))


(define A #(1 1 1 1 1))

Когда я пытаюсь это сделать, я получаю неправильный результат. В чем здесь проблема?

> (vectorSum A 0 4)
8
> (vectorSum A 0 1)
2
> (vectorSum A 0 3)
6
> (vectorSum A 1 3)
5
> (vectorSum A 1 2)
3

> (vectorSum A 0 1)
2
> (vectorSum A 1 2)
3

Взять (vectorSum A 0 3), когда я расширил рекурсию, я думал, что она должна быть

+ 1 + VectorSum (1 3)
    + 1 + VectorSum (2, 3)
        + 1 + VectorSum (3, 3)
            + 1   (I hit the first case, there is no more recursion)
= 4

Вместо этого я получаю 6. Почему?

Спасибо.


Посмотрите на 0,1 и 1,2, ответы не равны.

Ответы [ 2 ]

3 голосов
/ 13 февраля 2012

Ваше понимание того, как разворачивается рекурсия, является правильным.Ваша проблема в том, что вы забыли заключить в скобки свой звонок на vector-ref в первом случае.То, как вы написали это vector-ref V b, интерпретируется как три независимых выражения.Последний из которых (b) является значением выражения.Так как в вашем примере b равен 3, вы получите 1 + 1 + 1 + 3 = 6.

Просто добавьте скобки, чтобы сделать его вызовом функции, и он будет работать так, как вы хотите.

2 голосов
/ 13 февраля 2012

Ваш ответ должен выглядеть следующим образом:

(define (vectorSum V b e)
  (cond ((eqv? b e)
         (vector-ref V b))
        ((> b e)
         (eopl:error 'partialVectorSum "starting index must be smaller than or equal to the end index"))
        (else (+ (vector-ref V b) (vectorSum V (+ b 1) e)))))

Это была простая ошибка - вы забыли пару скобок в этой строке:

[ (eqv? b e) vector-ref V b]

Это должно было быть:

[ (eqv? b e) (vector-ref V b) ]

Без этих скобок вы на самом деле не вызываете процедуру vector-ref, вместо этого вы перечисляете некоторые символы и возвращаете последний, b в данном случае.Не забывайте всегда заключать вызов процедуры и его аргументы в круглые скобки, как вы это делали в части else.

...