2011-04-20 4 views
0

Je suis nouveau à Scheme, alors quelqu'un peut-il me donner un exemple? Il n'y a pas de variable locale dans Scheme, alors comment est-ce que je peux garder une trace du nombre de zéros qui sont rencontrés.Comment compter le nombre de zéros dans une liste?

J'ai essayé

#lang scheme 
(define zeroes 
    (lambda (ll) 
    (cond ((null? ll) 
      0) 
      (else (= 0 (car ll)))) 
    (zeroes (cdr ll)) 
) 
) 

Mais le compilateur se plaint:

cdr: expects argument of type <pair>; given() 

Merci,

Répondre

3

Voici ma solution (puisque l'OP est déjà affiché leur):

(define (count-zeroes lst) 
    (let loop ((lst lst) 
      (count 0)) 
    (cond ((null? lst) count) 
      ((zero? (car lst)) (loop (cdr lst) (+ count 1))) 
      (else (loop (cdr lst) count))))) 

Bien sûr, peut être considéré comme aucun traitement de ce sujet complet sans parler environ fold, qui est habituellement utilisé pour "résumer" une liste à un seul objet (comme nous le faisons pour cette question):

(define (count-zeroes lst) 
    (fold (lambda (elem count) 
      (if (zero? elem) (+ count 1) count)) 
     0 lst)) 
+0

Merci pour cette excellente solution. – Chan

1

Je garde cela à un niveau d'indice pour l'instant.

Votre fonction fait deux choses. D'abord, il calcule 0 si son argument est une liste vide, ou #t ou #f si son argument est une liste qui commence par 0 ou non. Ensuite, il jette ce résultat et s'appelle récursivement sur le reste de la liste.

Vous devrez faire deux choses pour faire ce travail: 1) combiner les résultats des tests individuels zéro en quelque sorte (pour une expérience de pensée, regardez votre code, comment serait-il jamais retourner la valeur 2 si la liste avait deux zéros?); 2) "bottom out" avec succès quand il s'appelle récursivement sur une liste vide.

+0

Je comprends la logique, la partie difficile était la syntaxe de sucre de schéma :(. Un exemple similaire serait un plus grand indice dans ce cas. – Chan

2

Tout compris la solution,

(define count 
    (lambda (lst) 
    (cond ((null? lst) 0) 
      ((= 0 (car lst)) (+ 1 (count (cdr lst)))) 
      (else (+ 0 (count (cdr lst)))) 
    )  
) 
) 
+0

Voilà de bonnes nouvelles. :-) Trois choses: 1. Vous pouvez utiliser 'zéro?' Pour vérifier si quelque chose est nul. 2. Veuillez formater votre code dans le style Scheme, pas dans le style C. ;-) (Plus spécifiquement, ne pas avoir de parenthèses pendantes.) 3. Vous pouvez utiliser '(else (count (cdr lst)))', sans ajouter de 0. :-) –

+0

@Chris Jester-Young: D'abord, merci pour le commentaire. Cependant, le style Scheme me fait un peu mal aux yeux. Je me sentais extrêmement mal à l'aise en faisant correspondre ces parenthèses dans ma tête. – Chan

+0

Si vous faites correspondre des supports dans votre tête, vous le faites mal! :-) Les plus expérimentés Schemers aiment utiliser quelque chose comme [Paredit] (http://mumble.net/~campbell/emacs/paredit.html) pour gérer les crochets pour eux. (Dans Paredit, les parenthèses sont _never_ mismatched --- le programme gère en s'assurant que toutes les parenthèses ouvertes correspondent à une parenthèse fermante.) –

Questions connexes