Aide en Scheme

Aide en Scheme - Langages fonctionnels - Programmation

Marsh Posté le 08-03-2011 à 10:41:54    

Bonjour,
Débutant en Scheme j'ai besoin d'aide.
J'ai écrit une fonction qui s'exécute bien mais j'ai un problème lorsque les 2 listes n'ont pas le même nombre d'éléments. En effet ( SI J'INTERPRETE BIEN LA SIGNATURE ) on me demande seulement un "#f" si pas le même nombre or mon algorithme sort des "#t" et des "#f". De plus j'exécute une fois de trop la fonction car il y a un point dans le résultat.
Si quelqu'un pouvait m'aider pour l'écriture de cette fonction ce serait sympa.
Merci d'avance.
;;; map2 : (alpha*beta --> gamma) * Liste[alpha] * Liste[beta] --> Liste[gamma}
;;; (map2 fn L1 L2) rend la liste obtenue en appliquant fn aux paires d'éléments de L1 et L2
;;; correspondants ou #f lorsque les 2 listes n'ont pas le même nombre d'éléments
;;; pas de zéro dans L2 car si fn = "/" erreur de division
(define (map2 fn L1 L2)
  (define (map2b fn L1 L2)
     (if (and (pair? L1) (pair? L2))
         (cons (fn (car L1) (car L2))(map2b fn (cdr L1) (cdr L2)))
         (if (or (pair? L1) (pair? L2))
             #f
             (list))))  
           
  (if (and (null? L1) (null? L2))
      (list)
  (map2b fn L1 L2)))
 
 
Bienvenue dans DrScheme, version 372 [3m].
Langage: Language pour LI101.
(map2)
|(map2 #<primitive:=> (1 2 3) (1 4))
|(#t #f . #f)
(#t #f . #f)
>

Reply

Marsh Posté le 08-03-2011 à 10:41:54   

Reply

Marsh Posté le 10-03-2011 à 10:42:54    

Tu dois calculer (avec un let) le reste de l'application de "map2b fn" aux arguments et si tu obtiens #f tu renvoies #f sinon tu concatènes (fn (car L) (car L2)) au reste.
Pour alléger le code, tu devrais utiliser cond plutôt que if : les deux listes sont -elles vides en même temps, une des deux listes est-elle vide..

Code :
  1. (cond ((and (null? L1) (null? l2))c ...)
  2.          (or (null? L1) (null? L2)) #f)
  3.          (else ...))


Reply

Marsh Posté le 11-03-2011 à 14:15:33    

;;; map2 : (alpha*beta --> gamma) * Liste[alpha] * Liste[beta] --> Liste[gamma}
;;; (map2 fn L1 L2) rend la liste obtenue en appliquant fn aux paires d'éléments de L1 et L2
;;; correspondants ou #f lorsque les 2 listes n'ont pas le même nombre d'éléments
;;; pas de zéro dans L2 car si fn = "/" erreur de division
;;; fn variable globale
(define (map2 fn L1 L2)
  (define (map2b L1 L2)
     (if (and (pair? L1) (pair? L2))        ;; les 2 listes sont présentes
         (cons (fn (car L1) (car L2))(map2b (cdr L1) (cdr L2)))
         (if (or (pair? L1) (pair? L2))     ;; 1 seule liste est présente
             #f
             (list))))  
           
  (if (and (null? L1) (null? L2))           ;; les 2 liste sont vides
      (list)
      (map2b L1 L2)))
 
(trace map2) (map2 + (list 1 2 3) (list 1 2 3))
 
Merci beaucoup  pour votre réponse mais je ne comprends pas désolé.
Si je mets un let avant le test des 2 listes présentes, je crée une erreur car dans les arguments de map2b j'ai (cdr L1).
 
Pour cond je suis d'accord mais dans mon écriture de code si je mets deux cond au lieu des if j'ai une erreur:
begin (possibly implicit): no expression after a sequence of internal definitions
 
Je tourne en rond et je prends une crise de nerf.
Merci encore

Reply

Marsh Posté le 11-03-2011 à 14:42:54    

Trap D a écrit :

Tu dois calculer (avec un let) le reste de l'application de "map2b fn" aux arguments et si tu obtiens #f tu renvoies #f sinon tu concatènes (fn (car L) (car L2)) au reste.
Pour alléger le code, tu devrais utiliser cond plutôt que if : les deux listes sont -elles vides en même temps, une des deux listes est-elle vide..

Code :
  1. (cond ((and (null? L1) (null? l2))c ...)
  2.          (or (null? L1) (null? L2)) #f)
  3.          (else ...))




Encore moi, j'ai voulu remplacer le if du define map en cond  
(cond (and (null? L1) (null? L2))   (list)        ;; les 2 liste sont vides
      (else
      (map2b L1 L2))))
 
Il me sort l'erreur : and: bad syntax in: and
 
Incompréhensible pour moi !!!!!!!!!!!!!
 

Reply

Marsh Posté le 11-03-2011 à 14:52:26    

Trap D a écrit :

Tu dois calculer (avec un let) le reste de l'application de "map2b fn" aux arguments et si tu obtiens #f tu renvoies #f sinon tu concatènes (fn (car L) (car L2)) au reste.
Pour alléger le code, tu devrais utiliser cond plutôt que if : les deux listes sont -elles vides en même temps, une des deux listes est-elle vide..

Code :
  1. (cond ((and (null? L1) (null? l2))c ...)
  2.          (or (null? L1) (null? L2)) #f)
  3.          (else ...))




J'ai compris pour les cond. ERREUR de ma part ( LES PARENTHESES ). Manque le point fondamental: #f
 
;;; (map2 fn L1 L2) rend la liste obtenue en appliquant fn aux paires d'éléments de L1 et L2
;;; correspondants ou #f lorsque les 2 listes n'ont pas le même nombre d'éléments
;;; pas de zéro dans L2 car si fn = "/" erreur de division
;;; fn variable globale
(define (map2 fn L1 L2)
  (define (map2b L1 L2)
     (cond ((and (pair? L1) (pair? L2))        ;; les 2 listes sont présentes
               (cons (fn (car L1) (car L2))(map2b (cdr L1) (cdr L2))))
           ((or (pair? L1) (pair? L2))       ;; 1 seule liste est présente
                #f)
     (else (list))))  
           
  (cond ((and (null? L1) (null? L2))   (list))        ;; les 2 liste sont vides
  (else   (map2b L1 L2))))
 
(trace map2) (map2 + (list 1 2 3) (list 1 2))

Reply

Marsh Posté le 11-03-2011 à 16:44:46    

J'avais vu quelque chose de ce style

Code :
  1. (define (map2 fn L1 L2)
  2.   (define (map2b fn L1 L2)
  3.     (cond ((and (null? L1) (null? L2)) L1)
  4.           ((or (null? L1) (null? L2)) #f)
  5.           (else (let ((x (map2b fn (cdr L1) (cdr L2))))
  6.                   (if (eq? x #f)
  7.                       #f
  8.                       (cons (fn (car L1) (car L2)) x))))))
  9.  
  10.       (map2b fn L1 L2))

Le let permet de savoir s'il y a eu un "problème" avant.

Citation :

> (map2 list '(1 2 3) '(1 4 6))  
((1 1) (2 4) (3 6))
> (map2 * '(1 2 3) '(4 5 6))
(4 10 18)
> (map2 * '(1 2 3) '(4 5))
#f

Reply

Marsh Posté le 12-03-2011 à 01:49:06    

Merci beaucoup pour votre aide, je m'arrachais les cheveux. Jamais je n'aurais pensé mettre le cas normal ( présence des deux listes ) après "else".
D'autre part en éliminant les 2 cas où au moins une liste est vide on peut faire "cdr".
BRAVO

Reply

Marsh Posté le 12-03-2011 à 08:21:21    

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.  
Écrire une fonction qui vérifie l'égalité de deux listes en utilisant la fonctionnelle filter.  
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 à 09:10:52    

J'ai besoin d'éclaircissements sur votre algorithme qui fonctionne très bien.
On boucle sur le let jusqu'à ce que L1 et L2 soient vides. Or dans les conditions on renvoie "#f" dans ce cas. Mais au retour lorsqu'on teste "#f" le test répond "faux" et se branche sur cons. Pourquoi ??
 
 
;; liste(nombre)*liste(nombre) --> liste(nombre ou booléen)
;; (map2 + '() '()) rend ()
;; (map2 + '(1 2 3) '(0 5 3)) rend (1 7 6)
;; (map2 / '(9 2 12) '(3 2 4)) rend (3 1 3) rend #f si 0 dans dénominateur  
;; (map2 = '(1 3 4) '(1 2 4) rend (#t #f #t)
;; (map2 fn '(9 2) '(3 2 4)) rend #f
 
(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
 
(trace map2) (map2 / (list 1 2 4) (list 1 2 3))
 

Reply

Marsh Posté le 12-03-2011 à 09:22:10    

debmaths a écrit :

J'ai besoin d'éclaircissements sur votre algorithme qui fonctionne très bien.
On boucle sur le let jusqu'à ce que L1 et L2 soient vides. Or dans les conditions on renvoie "#f" dans ce cas. Mais au retour lorsqu'on teste "#f" le test répond "faux" et se branche sur cons. Pourquoi ??
 
Désolé j'ai répondu trop rapidement. Le programme renvoie () et non "#f". Je comprends maintenant
 
;; liste(nombre)*liste(nombre) --> liste(nombre ou booléen)
;; (map2 + '() '()) rend ()
;; (map2 + '(1 2 3) '(0 5 3)) rend (1 7 6)
;; (map2 / '(9 2 12) '(3 2 4)) rend (3 1 3) rend #f si 0 dans dénominateur  
;; (map2 = '(1 3 4) '(1 2 4) rend (#t #f #t)
;; (map2 fn '(9 2) '(3 2 4)) rend #f
 
(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
 
(trace map2) (map2 / (list 1 2 4) (list 1 2 3))
 


Reply

Sujets relatifs:

Leave a Replay

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