2009-03-19 6 views
5

J'ai une fonction qui prend une liste qui a deux ou trois éléments.Comment puis-je savoir si une liste comporte un troisième élément?

;; expecting either ((a b c) d) or ((a b c) d e) 
(define (has-third-item ls) 
     (if (null? (caddr ls)) 
      false 
      true) 
    ) 

Mais ce code échoue avec

mcar: expects argument of type <mutable-pair>; given() 

sur le (null? (Ls Caddr)) expression.

J'ai aussi essayé

(eq? '() (caddr ls)) 

mais il ne fonctionne pas non plus. Comment savoir s'il y a un troisième article ou non?

+0

Juste curieux. Quelle langue est-ce s'il vous plaît? –

+0

La langue est Scheme – Kai

Répondre

9

Vous ne voulez pas caddr, vous voulez (if (null? (Cddr ls)) ... Ou utilisez juste la longueur pour trouver la longueur de la liste, et comparez-la à la valeur qui vous intéresse.

le «() qui met fin à une liste sera toujours en position de cdr d'une paire, donc chercher dans la position de la voiture (qui cao + r fera) ne va pas être productif.

4

le problème est que si vous avez une liste avec deux ou moins d'éléments, vous ne pouvez pas prendre la caddr de Essayer ceci:.

(define (has-third-item lst) 
    (<= 3 (length lst))) 

Il peut y avoir des cas où la longueur de la liste peut être inefficace (comme la liste contenant des millions d'éléments); dans ce cas, nous pouvons tester pour voir si la liste a une longueur zéro, un, ou deux à la main:

(define (has-third-item lst) 
    (not (or (null? lst) 
      (null? (cdr lst)) 
      (null? (cddr lst))))) 

modifier: En ce qui concerne les twoother réponses, tout en prenant le cddr peut fonctionner dans ce cas le domaine d'entrée consiste en liste avec deux ou trois éléments, has-third-item échouerait toujours pour les listes avec zéro ou un. Dans l'intérêt de la généralité, je suggère d'utiliser une solution qui fonctionne pour n'importe quel domaine.

1

à condition de connaître votre liste a deux ou trois éléments (comme vous le dire a), vous pouvez faire

(define (has-third-item? l) 
    (not (null? (cddr l)))) 

Vous vérifier si la deuxième cellule contre (cddr l) a une cdr ou non. Vous n'avez pas à vérifier si l lui-même est nul ou si j'ai seulement un élément, sauf si vous voulez une fonction plus générique.

0

essayer ...

(and l (cdr l)(cddr l)) 
0

Pourquoi ne pas utiliser (troisième ls)

renverra le troisième élément ou NIL si aucun est présent.