Scheme - filter

Scheme - filter - Langages fonctionnels - Programmation

Marsh Posté le 12-03-2011 à 19:51:56    

Bonjour,  
Je vais abuser de votre serviabilité.  
Voici un exercice sur lequel je bute mais cette fois je n'ai vraiment aucune idée pour le faire, je suis vraiment sec. En effet "filtre" a deux arguments: un "test?" dont le résultat est obligatoirement un booléen et une seule liste  
Dans tout cet exercice, on considérera que les listes sont de longueur égales et contiennent des données de type String.  
[b]Écrire une fonction qui vérifie l'égalité de deux listes en utilisant la fonctionnelle filter.  [/b]
Une idée SVP. Merci pour votre aide  
 
(define (xfiltre test? L)  
  (if (pair? L)  
      (let ((k (xfiltre test? (cdr L))))  
        (if (test? (car L))  
            (cons (car L)  
            k)  
            k))  
   (list)))
 

Reply

Marsh Posté le 12-03-2011 à 19:51:56   

Reply

Marsh Posté le 13-03-2011 à 09:58:43    

Tu peux utiliser ton map2 pour constituer une seule liste avec les deux listes L1 et L2 (fn peut être cons ou list)
Tu passes ensuite le résultat le l'application de map2 à filtre qui teste ensuite les éléments uns par un (étudie le car et le cdr (ou le cadr) de l'élément) .

Reply

Marsh Posté le 13-03-2011 à 13:24:08    

OK j'ai fait comme vous avez préconisé mais xfiltre2 ne correspond pas à xfiltre (filter) car on traite une association de 2 nombres et non plus un seul. De plus, il me semble que la solution doit être plus simple , je n'en suis qu'au début de Scheme. Depuis 2 semaines j'essaie en jouant sur test ? mais je n'y arrive pas. Merci pour votre aide
 
define (map2 fn L1 L2)
  (cond ((and (null? L1) (null? L2)) L1)             ;; les 2 liste sont vides
        ((or (null? L1) (null? L2)) #f)              ;; 1 seule liste est présente
        ((and (eq? fn /) (= (car L2) 0)) #f)         ;; erreur si division et dénominateur=0
        (else
             (let ((x (map2 fn (cdr L1) (cdr L2))))  ;; les 2 listes sont présentes
             (if (eq? x #f)                          ;; test retour de map2
                 #f
                (cons (fn (car L1) (car L2)) x))))))   ;; traitement chiffre par chiffre
 
(define (xfiltre test? L)
  (if (pair? L)
      (let ((k (xfiltre test? (cdr L))))
        (if (test? (car L))
            (cons (car L)
            k)
            k))
   (list)))
 
(define (xfiltre1 test1? L3 L4)
  (let ((tL (map2 list L3 L4)))
         
    (define (xfiltre2 test1? tL)    
    (if (pair?  tL)
        (let ((couple (car tL))
              (k (xfiltre2 test1? (cdr tL))))
        (if (test1? (car couple) (cadr couple))
            (cons (car couple) k)
             #f))
        (list)))
         
    (xfiltre2 test1? tL)))
(trace xfiltre1) (xfiltre1 = (list 1 2 3) (list 1 4 3))

Reply

Marsh Posté le 13-03-2011 à 16:16:24    

Je vais abuser mais comme j'ai un informaticien averti en langage Scheme sous la main ...........
Si je ne me trompe pas, on peut mettre dans le code du programme (let (x (cadr L)) après (let (x (car L)); la valeur de x est bien modifiée !!!
Je ne comprends pas pourquoi mon 2ème let n'est pas pris en compte. cela fait 2 jours que je planche sur ce problème, merci pour ceux qui souffrent.
 
;;; liste (nombre --> liste ( 2 nombres )
;;; ext-liste: rend une liste avec 2 nombres: le mini et le maxi des arguments de la liste entrée
(define (ext-liste L)
 (let ((x (car L))
       (y (car L)))        
(define (ext1-liste L)
  (if (pair? (cdr L))
    ((if (>= (cadr L) x)        ;; recherche du maxi de la liste
        (let ((x (cadr L)))
        (if (< (cadr L) y)        ;; recherche du mini de la liste
           (let ((y (cadr L)))
           ))))
        (ext1-liste (cdr L)))
  (list x y)))
     
   (ext1-liste L)))
 
(trace ext-liste) (ext-liste (list 1 3 2 4)

Reply

Marsh Posté le 14-03-2011 à 09:10:31    

Je crois que vous êtes partis sur un mauvais pied.
Je pense que vous devriez travailler avec une sous fonction qui utilise deux arguments, la liste à explorer et une liste qui contient le min et la max déjà rencontrés (initialisés au premier élément de la liste initiale).
A chaque étape vous comparer le premier élément de la liste avec les deux éléments de la liste résultat.

Reply

Marsh Posté le 14-03-2011 à 12:35:12    

Trap D a écrit :

Je crois que vous êtes partis sur un mauvais pied.
Je pense que vous devriez travailler avec une sous fonction qui utilise deux arguments, la liste à explorer et une liste qui contient le min et la max déjà rencontrés (initialisés au premier élément de la liste initiale).
A chaque étape vous comparer le premier élément de la liste avec les deux éléments de la liste résultat.


 
A un moment donné j'étais parti sur cette hypothèse mais je ne m'en étais pas sorti
 
(define (xxx L)
 (list (car L) (car L)))  
   
(define (yyy L)
  (let ((rL (xxx L)))
 
Lorsque je me reboucle sur yyyy la liste rL est réinitialisée !!!
Merci pour votre aide
   

Reply

Marsh Posté le 14-03-2011 à 14:52:13    

Trap D a écrit :

Je crois que vous êtes partis sur un mauvais pied.
Je pense que vous devriez travailler avec une sous fonction qui utilise deux arguments, la liste à explorer et une liste qui contient le min et la max déjà rencontrés (initialisés au premier élément de la liste initiale).
A chaque étape vous comparer le premier élément de la liste avec les deux éléments de la liste résultat.


 
J'avais une autre solution mais je n'arrive pas à tester > et < en séquence. Cela fonctionne pour < ou > mais je ne vois pas comment lier les 2 !!! Pour < il faudrait mettre (car L) dans le deuxième argument de list
define (min-nbre-max L)
  (if (pair? (cdr L))
    (let ((k (min-nbre-max (cdr L))))
       (cond ((> (car L) (car k)) (list (car L) ))
       (else     k )))  
   (list (car L))))
 
(trace min-nbre-max) (min-nbre-max (list 2 3 1 5))

Reply

Marsh Posté le 14-03-2011 à 16:48:32    

debmaths a écrit :


 
J'avais une autre solution mais je n'arrive pas à tester > et < en séquence. Cela fonctionne pour < ou > mais je ne vois pas comment lier les 2 !!! Pour < il faudrait mettre (car L) dans le deuxième argument de list
define (min-nbre-max L)
  (if (pair? (cdr L))
    (let ((k (min-nbre-max (cdr L))))
       (cond ((> (car L) (car k)) (list (car L) ))
       (else     k )))  
   (list (car L))))
 
(trace min-nbre-max) (min-nbre-max (list 2 3 1 5))


 
 
Je pense que cette fois-ci je suis sur la bonne voie. En tatonnant voila ce que j'ai trouvé:
(define (min-nbre-max L)
  (if (and (pair? L) (pair? (cdr L)))
    (let ((k (min-nbre-max (cdr L))))
       (cond ((< (car L) (car k)) (list 1 (car L)))         ;; (car k) 1ère position de list !!!!!!!!!!!!!!!!
             ((> (car L) (cadr k)) (list (car L) 1))      
       (else     k )))  
    (list (car L) (car L) )))
(trace min-nbre-max) (min-nbre-max (list 2 4 3 5 1))
 
Il me reste deux questions:
-- pourquoi (car k) donne la 1ère position de list et non de (cdr L ) ? j'ai trouvé en débuggant
-- comment mettre (car L ) dans les deux positions de list.
 
J'ai vraiment la grosse tête et là je pense que ce n'est pas un problème d'algorithme mais d'écriture Scheme.
Merci pour votre aide
 

Reply

Marsh Posté le 14-03-2011 à 18:49:56    

debmaths a écrit :


-- comment mettre (car L ) dans les deux positions de list.

En faisant simplement ceci (list (car L) (car L)) comme vous l'avez écrit à un moment.
 
Je voyais quelque chose du style

(define (min-nbre-max L)  
  (define (min-nbre-max-1 L R)  
     (cond ((null? L) R) ; si la liste est vide on revoie le résultat
             ( (< (car L) (car R)) ....) ; si le premier élément de la liste est plus petit que le min déjà rencontré
             ( (<>(car L) (cadr R)) ....) ; si le premier élément de la liste est plus grand que le max déjà rencontré
             (else ..))) ; dans les autres cas que fait-on ?
  (min-nbre-max-1 (cdr L) (list (car L) (car L))) ; on applique la fonction locale a la liste dont on a enleve le premier élément


Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed