2010-11-14 12 views
1

Cette fonction récursive semble fonctionner correctement, en ajoutant à la liste de résultats les lettres exactes que je veux, B et C, et quand elle se termine, elle voit correctement que le dernier élément a été atteint. Il exécute ensuite le cas de base et une erreur se produit que je ne peux pas expliquer. Qu'est ce qui cause cette erreur?Erreur de récurrence de schéma

(define(preceding-R X Vector result)  
     (if (eq? '() (cdr (vector->list Vector))) 
       result 
       (helper X Vector result))) 

(define (helper X Vector result) 
    (if(eqv? X (cadr (vector->list Vector))) ((set! result (cons result (car (vector->list Vector)))) (preceding-R X (list->vector (cdr (vector->list Vector))) result)) 
          (preceding-R X (list->vector (cdr (vector->list Vector))) result))) 

(preceding-R 'a #(b a c a) '())) 

L'erreur:

procedure application: expected procedure, given: #; arguments were: ((() . b) . c)

+1

Veuillez formater votre code et expliquer brièvement ce que le code doit faire. – ffriend

Répondre

4

est ici un code qui ne sont pas "absolument horrible":

(define preceding-R 
    (lambda (x vec) 
    (define helper 
     (lambda (ls) 
     (cond 
      ((null? ls) '()) 
      ((null? (cdr ls)) '()) 
      ((eq? (cadr ls) x) (cons (car ls) (helper (cdr ls)))) 
      (else (helper (cdr ls)))))) 
    (helper (vector->list vec)))) 

> (preceding-R 'a #(b a c a)) 
(b c) 

Eli Barzilay a un point; si je classement le code d'origine, je ne serais probablement attribuer moins de crédit moitié à cause des choses qu'il a fait remarquer:

  • set! devrait être évitée dans la plupart des cas, et est généralement pas autorisés sur les problèmes de devoirs impliquant le code régime de base . Avoir à utiliser set! est un dire d'habitude que la récursivité n'est pas trop bien comprise. Puisque begin "jette" les résultats de tout sauf la dernière expression, cela signifie que les expressions sans queue ont des effets secondaires (comme set!) et donc begin n'apparaît généralement pas non plus dans les problèmes d'éducation.
  • Conversion de va-et-vient encore et encore et encore et encore est évidemment une perte. Une conversion suffira, mais vous auriez probablement pu utiliser des listes au lieu de vecteurs pour commencer. Les listes sont la structure de données la plus utilisée dans Scheme, d'autant plus qu'elles fonctionnent bien avec la récursivité.
  • Votre code d'erreur sur une liste vide dans votre deuxième ligne: (preceding-R 'a #()) => Error: Attempt to apply cdr on '()
  • Si vous faites utilisation set! modifier résultat, alors il n'y a aucune raison de passer autour résultat. C'est un bagage supplémentaire.
  • dernier point d'Eli est que vous pouvez écrire:

.

(define (helper X Vector result) 
    (preceding-R X (list->vector (cdr (vector->list Vector))) 
       (if (eq? X (cadr (vector->list Vector))) 
        (cons (car (vector->list Vector)) result) 
        result))) 

d'économiser du code répété.

1
(define (preceding-R X Vector result)  
    (if (eq? '() (cdr (vector->list Vector))) 
    result 
    (helper X Vector result))) 

(define (helper X Vector result) 
    (if (eqv? X (cadr (vector->list Vector))) 
    (begin 
     (set! result (cons (car (vector->list Vector)) result)) 
     (preceding-R X (list->vector (cdr (vector->list Vector))) result)) 
    (preceding-R X (list->vector (cdr (vector->list Vector))) result))) 

(preceding-R 'a #(b a c a) '()) 

J'ai ajouté commencer appel. Si vous voulez insérer plusieurs expressions si vous ne pouvez pas les placer dans(), cela a été interprété comme un appel de fonction sur void (retourné par set!) Avec l'argument retourné par l'appel récursif à-R -précédente.

+0

merci beaucoup, je savais que le problème était lié à ça, mais j'avais essayé d'utiliser cond pour résoudre ce problème, puisque je savais que ça commençait par défaut. apparemment, je ne l'appliquais pas correctement. Merci encore. – cliff259

+3

Ce code est absolument horrible. Il utilise 'set!' Sans raison valable, il utilise 'begin' juste pour ça, il va lancer des erreurs sur certains cas, il continue à convertir le vecteur en liste et en retour aux vecteurs, il a' if' au niveau externe de 'helper' quand il pourrait facilement être poussé à l'intérieur du dernier document, etc. –