IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Caml Discussion :

verification qu'une liste est triée


Sujet :

Caml

  1. #21
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    291
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 291
    Points : 49
    Points
    49
    Par défaut
    Re bonjour, j'ai à nouveau un petit problème d'algo je dirais.

    Je dois faire le produit cartésien de deux listes.
    Voici ce que j'ai fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    let rec produit_cartesien l1 l2=
    	 match (l1,l2) with
    	 |([],_) | (_,[])-> []
    	 |((h1::t1),(h2::t2)) -> (h1,h2) :: (produit_cartesien t1 h2 @ produit_cartesien l1 t2) ;; ;;

  2. #22
    Membre actif Avatar de Steki-kun
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 222
    Points : 281
    Points
    281
    Par défaut
    Je suis pas sûr (même certain en fait) que ton problème vienne de Caml, tu as essayé d'écrire une définition "mathématique" récursive du produit cartésien de 2 ensembles finis ?
    Petit truc pour savoir si ton code a la moindre chance d'être juste: on va faire un peu d'interprétation abstraite, je cherche même pas à comprendre ce que fait ta fonction, mais je regarde le nombre d'éléments dans le résultat, c'est sensé être n * m où n et m sont les longueurs des arguments. Or dans la deuxième branche on obtient:

    1 + n * (m-1) + (n-1)*m

    soit à peu près le double du nombre attendu d'éléments.

    S.

  3. #23
    Membre régulier
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    102
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2010
    Messages : 102
    Points : 110
    Points
    110
    Par défaut
    Salut,

    Je suis pas sûr que ce soit une bonne idée, mais en tous cas moi ça m'aide à écrire ce genre de fonctions :

    Il faut balayer la première liste, mais à chaque étape il faudra également balayer la deuxième liste (d'où la complexité en n.m). Or c'est un peu compliqué à écrire d'un coup. Du coup ce que je fais c'est que plutôt que d'écrire une fonction compliquée, j'écris deux fonctions simples :

    1. Une qui fait le "produit cartésien" d'un ensemble à un élément et d'un ensemble à m éléments (en fait le premier argument qu'elle prendra ne sera pas un ensemble à un élément mais tout simplement cet élément).

    2. Une qui d'arguments un ensemble à n éléments et un ensemble à m élément va renvoyer le produit cartésien de ces deux ensembles : elle va balayer la première liste en appliquant la première fonction à chacun ses éléments (et à la deuxième liste).

    L'avantage c'est que les deux fonctions sont super simples à écrire individuellement, donc globalement ça rend le problème simple.

    Par contre je ne sais pas si c'est une bonne pratique, notamment je ne sais pas s'il vaut mieux définir la première fonction globalement ou localement... Je sais même pas si ça fait une différence, peut-être pour la lisibilité ?

    Un code sera peut-être plus parlant mais attention, je ne garantis absolument pas que celui-ci est bon ! (par contre je l'ai essayé et a priori ça marche)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    let cart l1 l2 = 
      let rec aux1 h1 l2 l3 =
        match l2 with
        | [] -> l3
        | h2::t2 -> aux1 h1 t2 ((h1,h2)::l3)
      in
      let rec aux2 l1 l2 l3 =
        match l1 with
        | [] -> l3
        | h1::t1 -> aux2 t1 l2 (aux1 h1 l2 l3)
      in
      aux2 l1 l2 []
    ;;

  4. #24
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    291
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 291
    Points : 49
    Points
    49
    Par défaut
    Oui je sais bien j'ai bien dit que j'avais plutot un problème d'algo que de caml !

  5. #25
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 681
    Points
    18 681
    Par défaut
    je verrais plutôt quelque chose dans ce style... écrit naïvement ça donnerait cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    # let rec produit_cartesien l1 l2=
     match (l1,l2) with
     |([],_) | (_,[])-> []
     |((h1::t1),(h2::t2)) -> (h1,h2) :: (produit_cartesien ([h1]) t2) @ (produit_cartesien t1 ([h2])) @ (produit_cartesien t1 t2)
    ;;
    val produit_cartesien : 'a list -> 'b list -> ('a * 'b) list = <fun>
    # produit_cartesien ([0;1;2]) (['a';'b']) ;;
    - : (int * char) list =
    [(0, 'a'); (0, 'b'); (1, 'a'); (2, 'a'); (1, 'b'); (2, 'b')]
    #



    pas dur d'optimiser (beaucoup) ce code... à toi de jouer

  6. #26
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    291
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 291
    Points : 49
    Points
    49
    Par défaut
    Ta fonction renvoit [(0, 'a'); (0, 'b'); (1, 'a'); (2, 'a'); (1, 'b'); (2, 'b')].

    Or elle devrait renvoyer [(0, 'a'); (1, 'a'); (2, 'a'); (0, 'b'); (1, 'b'); (2, 'b')].

  7. #27
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    291
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 291
    Points : 49
    Points
    49
    Par défaut
    Voilà ce que j'ai fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    let l1= ["a";"b"] ;;
    let l2 = [1;2;3];;
     
     
    let rec produit_cartesien l1 l2=
    		match (l1,l2) with
    		|([],_) | (_,[])-> []
    		|((h1::t1),(h2::t2)) -> (h1,h2):: (produit_cartesien t1 ([h2]) @ produit_cartesien ([h1]) t2 @ produit_cartesien t1 t2);
    Mais ça me renvoit ["a", 1; "b", 1; "a", 2; "a", 3; "b", 2; "b", 3] au lieu de

    ["a", 1; "b", 1; "a", 2; "b", 2; "a", 3; "b", 3].

    Je n'y arrive pas,franchement je commence à désespérer...

  8. #28
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    291
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 291
    Points : 49
    Points
    49
    Par défaut
    Aleluia j'y suis enfin arrivé,comme quoi meme moi ... bref.

    J'ai opté pour faire une sous fonction qui fait le produit cartésien entre une liste et un singleton.Ensuite je l'ai utilisé pour faire le produit cartésien des deux listes.

    Voici:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    let rec fonction l n =
    	match l with
    	|[] -> []
    	|(head::tail) -> (head,n)::(fonction tail n);;
     
    let rec produit_cartesien l1 l2=
    	match (l1,l2) with
    	|([],_) | (_,[])-> []
    	|((h1::t1),(h2::t2)) -> fonction l1 h2 @ produit_cartesien l1 t2;;
    Bref ouf merci à vous !

  9. #29
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonsoir,

    Vraiment à la va-vite, parce que je n'ai vraiment pas beaucoup de temps à y consacrer, il me semble que tu peux optimiser ce code avec un système de type continuations (en gros tu passes à chaque fonction la liste en construction pour éviter une coûteuse concaténation). Ça va tout rendre tail-rec. Je te donne le code auquel je pense, pas testé donc prudence (en fait je soupçonne que le résultat est le bon mais l'ordre inversé) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    let rec fonction n acc = function
      | [] -> acc
      | head :: tail -> fonction n ((head, n) :: acc) tail
     
    let produit_cartesien l1 l2 =
      let rec loop acc l1 l2 =
        match l1, l2 with
        | [], _ | _, [] -> acc
        | _, h2 :: t2 -> loop (fonction h2 acc l1) l1 t2
      in loop [] l1 l2
    Je n'ai malheureusement pas le temps de détailler le pourquoi du comment de ce code.

    Cordialement,
    Cacophrène

  10. #30
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 681
    Points
    18 681
    Par défaut
    Citation Envoyé par guipe Voir le message
    Ta fonction renvoit [(0, 'a'); (0, 'b'); (1, 'a'); (2, 'a'); (1, 'b'); (2, 'b')].

    Or elle devrait renvoyer [(0, 'a'); (1, 'a'); (2, 'a'); (0, 'b'); (1, 'b'); (2, 'b')].
    depuis quand l'ordre importe ?

  11. #31
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    968
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 968
    Points : 1 412
    Points
    1 412
    Par défaut
    Depuis que l'on renvoie une liste.

  12. #32
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 681
    Points
    18 681
    Par défaut
    Citation Envoyé par LLB Voir le message
    Depuis que l'on renvoie une liste.
    la liste n'est pas juste une représentation interne de l'ensemble ?
    c'est souvent le cas dans les TD pour débutants (il faut alors qu'ils fassent attention aux doublons )

    par ailleurs, rien ne dit que la liste est ordonnée, et donc que l'on doit s'attarder sur la façon de mettre les éléments dans le résultat final

  13. #33
    Membre actif Avatar de Steki-kun
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 222
    Points : 281
    Points
    281
    Par défaut
    Je plussoie Gorgonite !
    Et d'ailleurs j'ajoute que si ces listes ne sont pas des ensembles finis, il aurait fallu définir ce que ça veut dire que produit cartésien

Discussions similaires

  1. Récuperer les n valeurs plus grandes d'une liste non triée
    Par Oberown dans le forum Algorithmes et structures de données
    Réponses: 17
    Dernier message: 26/07/2007, 13h34
  2. Verification d'une liste deroulante
    Par roxxxy dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 12/03/2007, 12h09
  3. Comment savoir si une liste est vide?
    Par erfindel dans le forum Access
    Réponses: 2
    Dernier message: 14/02/2007, 16h20
  4. [XSLT] vérification si une chaîne est une date
    Par yos dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 22/06/2006, 16h06
  5. Réponses: 2
    Dernier message: 10/06/2006, 18h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo