2010-11-11 10 views
4

Nouveau dans le schéma ici et j'ai quelques difficultés à apprendre à faire des boucles. J'essaie de faire une fonction qui va prendre un objet et un vecteur, et ensuite parcourir le vecteur jusqu'à ce qu'il trouve cet objet. Lorsque l'objet est trouvé, il retourne alors une liste contenant tous les éléments du vecteur avant l'objet. Mon code est ci-dessous. Tout ce qu'il retournera est combien d'itérations la boucle do est passée, au lieu de la liste que je le veux. Si quelqu'un pouvait m'aider avec la syntaxe, je l'apprécierais grandement. Merci! (Ce serait revenir idéalement (1 2))Faire une boucle itérative dans le schéma

(define(vector-test-iterative X Vector)  
     (do ((i 0 (+ i 1))) (< i (vector-length Vector)) 
      (if (eqv? X (vector-ref Vector i)) 
       (= i (vector-length Vector)) 
       (cons (vector-ref Vector i) (ls '()))) 
      ls)) 


(vector-test-iterative '4 #(1 2 4 3 5)) 
+0

Dans le schéma, parens ne vont pas sur leur propre ligne. L'indentation devrait être suffisante pour mettre à part les blocs de code. – erjiang

Répondre

4

Si vous utilisez Racket, alors il n'y a pas besoin d'utiliser do, qui n'a jamais été populaire parmi les intrigants de toute façon. Il y a toute une gamme d'itérateurs - recherchez for dans les documents, et les éléments qui commencent par for. Par exemple, votre code se résume à

#lang racket 
(define (values-before x vector) 
    (for/list ([y (stop-before (in-vector vector) 
          (lambda (y) (eqv? x y)))]) 
    y)) 

(Si vous voulez vraiment utiliser do, alors vous manque une paire de parens autour du test, et vous devez ajouter une liaison pour l'accumulateur.)

+0

merci pour la réponse. ce que je veux faire est de stocker dans une liste toutes les valeurs qui apparaissent dans le vecteur avant une autre valeur. Donc si mon vecteur est 1 2 3 4 et que je passe 4, je veux que la fonction retourne 1 2 3. J'ai essayé d'exécuter votre code et j'ai reçu une erreur que "for/list" était une référence à un identifiant indéfini . mais je vais certainement regarder dans les boucles. – cliff259

+0

Donc, mon estimation initiale de ce que vous essayez de faire était mal - je l'ai révisé pour correspondre à ce que vous voulez maintenant. En ce qui concerne l'erreur, vous devriez utiliser le langage "déterminer la langue de la source", et assurez-vous que vous avez le "' #lang racket' "en haut. (Et j'espère que vous utilisez une version récente.) –

1

Une solution qui utilise une boucle nommée. Cleaner (à mon avis!) Que la version do et devrait fonctionner sur tout r5rs Scheme:

;; Extracts the sublist of `lst` up to `val`. 
;; If `val` is not found, evaluates to an empty list. 
(define (upto val lst) 
    (let loop ((res null) (lst lst)) 
    (cond ((null? lst) null) 
      ((eq? val (car lst)) (reverse res)) 
      (else (loop (cons (car lst) res) (cdr lst)))))) 

;; Adapts the above procedure to work with vectors. 
(define (vector-upto val vec) 
    (list->vector (upto val (vector->list vec)))) 

;; test 
(vector-upto 6 #(1 2 3 4 5)) 
=> #0() 
(vector-upto 5 #(1 2 3 4 5)) 
=> #4(1 2 3 4) 
(vector-upto 3 #(1 2 3 4 5)) 
=> #2(1 2) 
(vector-upto 1 #(1 2 3 4 5)) 
=> #0() 
+0

Je ne suis pas sûr que cette solution (en utilisant la syntaxe 'let' alternative) est plus claire qu'un' do', s'il y a un effet secondaire avant chaque appel du corps. Mais je pense que c'est une question de préférence personnelle. Cependant +1 pour votre suggestion. –

Questions connexes