2010-11-11 19 views
1

En essayant de compter le nombre d'éléments positifs dans une liste. Voici ce que j'ai jusqu'à présent:Nombre d'éléments positifs dans la liste

(define howMany 
    (lambda (list) 
     (cond 
     [(not (list? list)) 0] 
     [(null? list) 0] 
     [(> list 0) (+ 1 (howMany (cdr list)))]))) 

Il continue à me donner une erreur, « attend de type réel », comment voulez-vous résoudre ce problème?

Oh im appeler cela comme si:

(howMany '(6 7 8)) 
+1

Sûrement, vous voulez dire le schéma et non du schéma? –

Répondre

0

Il y a quelques bugs dans votre code.

(> list 0) devrait être (> (car list) 0) que vous voulez vérifier si le premier élément de la liste est supérieure à 0. Vous ne pouvez pas appliquer l'implémentation par défaut de > à une liste non plus.

(+ 1 (howMany (cdr list))) échoue également car howMany n'évalue pas toujours un nombre. Vous devez maintenir un compteur en le passant en argument à la procédure appelée récursivement. Une façon de le faire est:

(define (howmany lst) 
    (let loop ((n 0) (lst lst)) 
    (if (null? lst) n 
     (loop (if (> (car lst) 0) (add1 n) n) (cdr lst))))) 

Test:

> (howmany '(1 2 3 4 5)) 
5 
> (howmany '(1 2 3 -4 5)) 
4 
> (howmany '(1 -2 3 -4 5)) 
3 
> (howmany '(-1 -2 3 -4 5)) 
2 
0

Voici votre problème: (> list 0)

Vous comparez une liste à un certain nombre. Essayez (> (length list) 0) ou (not (null? list)). Ou quel que soit le mot clé Scheme pour "condition par défaut dans un bloc cond" est. Editer: C'est ce que vous obtenez lorsque vous vous concentrez sur les messages d'erreur avant tout. Gareth a raison, bien sûr.

+0

Le schéma n'a pas de mot-clé spécial pour "condition par défaut dans un cond". Vous donnez simplement '# t' (mot-clé du scheme pour true) comme condition lorsque vous voulez une condition par défaut. – sepp2k

+0

Ahh merci. J'ai essayé un peu le Common Lisp, donc Scheme ressemble à un dialecte étranger. – Mihai

+0

"aucun mot-clé spécial" - il y a 'else' dans [R6RS] (http://www.r6rs.org/final/html/r6rs/r6rs-ZH-14.html#node_sec_11.4.5) –

4

Vous ne pouvez pas attendre (> list 0) au travail - list est une liste, mais > s'attend à ce que ses arguments soient des nombres.

Vous voulez voir si l'élément premier de la liste est positif, ce qui devrait être (> (car list) 0).

Cependant: il y a un plus gros problème avec votre code: que se passe-t-il si le premier élément est négatif ou nul?

+0

Voulez-vous dire «# t» et pas seulement «t»? – erjiang

+0

Oui, '# t'. Je suis plus un lisper qu'un intrigant, et j'oublie souvent ces petites différences. –

+0

Je vois votre point, si le premier nombre est zéro ou négatif, il ne fait rien. Si la liste ressemble à ceci: '(1 2 -3) il se bloque et me dit attendre le numéro de type. –

0
positiveCounter(seq) 
    if typeof(first(seq)) == num 
     if first(seq) > 0 
      return positiveCounter(rest(seq) + 1 
     else 
      return positiveCounter(rest(seq) 
    else 
     #Handle Errors Somehow. 

Pseudocode pour l'algorithme récursif que j'utiliserais. Je ne connais ni Scheme ni Clojure (que vos crochets rappellent). Ou vous pouvez écrire une approche applicative considérablement plus snazzante dans Common Lisp - extra-lignes nouvelles pour plus de lisibilité.

(defun positiveCounter (seq) 
    (reduce #'+ 
      (mapcar 
      #'(lambda (x) 
       (if (atom x) 
        (if (> x 0) 1 0) 
        0)) 
      seq))) 
+0

Les crochets autorisés par certains schémas sont purement lisibles - ils sont identiques aux parens. L'équivalent Scheme est assez proche: '(define (SEQ positif-counter) (applique + (map (lambda (x) (if (nombre? X) (si (> x 0) 1 0))) seq))) ' – Chuck

+0

@Chuck: bon à savoir. –

+0

@Chuck: '(if (et (nombre? X) (> x 0)) 1 0)', sûrement? –