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

Haskell Discussion :

fonction pour enlever les doublons


Sujet :

Haskell

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    311
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2005
    Messages : 311
    Points : 97
    Points
    97
    Par défaut fonction pour enlever les doublons
    Salut tout le monde

    je suis un peu perdue, je voudrais faire une fonction Haskell qui fait la chose suivante:

    je donne une liste des cd à ma fonction , et elle doit me retourner la même liste sans doublons et en additionnant le nombre de cd qui sont pareils (meme nom et meme langue)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
     
    data Lang = Fr | Ang | Ar  diriving (Eq, Show)
    data Cd = disque String Int Lang diriving (Eq, Ord)
     
     
    sansDoublons :: [Cd] -> [Cd]
    sansDoublons [] = []
    sansDoublons (c:cs) = 
    	sansDoublons cs ++ enlever c cs
     
     
    enlever :: Cd -> [Cd] -> [Cd]
    enlever c1 [] = c1
    enlever (disque n q u) (disque n1 q1 u1:ys) = 
    	|n==n1 && u==u1  = (disque n1 (q1 + q) u1) 
    	|otherwise = enlever(disque n q u) : ys
    bien évidement cette fonction ne me donne pas exactement ce que je veux!!

    Merci d'y jeter un œil et de me dire ce qui ne va pas

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    311
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2005
    Messages : 311
    Points : 97
    Points
    97
    Par défaut
    Hello , Personne ne peux aider !!
    Merci

  3. #3
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Bonjour

    Je ne sais pas ce qui ne va pas dans ton code, tout ce que je peux dire, c'est que ce qui suit fonctionne chez moi !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    data Lang = Fr | Ang | Ar  deriving (Eq, Show)
    data Cd_In =  Disque String Lang deriving (Eq, Show)
    data Cd_Out = Cd String Int Lang deriving (Eq, Show)
     
     
    sansDoublons :: [Cd_In] -> [Cd_Out]
    sansDoublons [] = []
    sansDoublons ( (Disque nom  lang) : cs) = 
    	let (x, ys) = compacter  (Cd nom 1 lang) cs
    		in	x : sansDoublons ys           
     
     
    compacter :: Cd_Out -> [Cd_In] -> (Cd_Out , [Cd_In])
    compacter x [] = (x, [])
    compacter (Cd nom1 val lang1)((Disque nom2 lang2) : ys) = 
    	if (nom1 /= nom2 || lang1 /= lang2)
    	then  let (x , ys1) = compacter (Cd nom1 val lang1) ys 
              in (x , (Disque nom2 lang2) : ys1)
    	else  compacter (Cd nom1 (val + 1) lang1) ys
     
     
     
     
    main = do
    	print $ sansDoublons  [Disque "nom1"  Fr, Disque "nom2"  Fr, Disque "nom1"  Fr]
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  4. #4
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Finalement, en cherchant un peu j'ai corrigé ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    data Lang = Fr | Ang | Ar  deriving (Eq, Show) <== de et non di
    data Cd = Disque String Int Lang deriving (Eq, Show)  <== la j'ai changé mais je ne sais pas pourquoi ça marche
     
     
    sansDoublons :: [Cd] -> [Cd]
    sansDoublons [] = []
    sansDoublons (c:cs) = 
    --	sansDoublons cs ++ enlever c cs <== faux tu gardes Cs en ajoutant a la suite cs sans C
    	enlever c (sansDoublons cs) 
     
    enlever :: Cd -> [Cd] -> [Cd]
    enlever c1 [] = [c1]
    enlever (Disque n q u) ((Disque n1 q1 u1):ys) = 
    	if (n==n1 && u==u1)
    		then enlever (Disque n1 (q1 + q) u1) ys
    	    else (Disque n1 q1 u1) : enlever(Disque n q u) ys
     
    main = do
    	print $ sansDoublons  [Disque "nom1"  2 Fr, Disque "nom2" 3 Fr, Disque "nom1" 4 Fr]
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    311
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2005
    Messages : 311
    Points : 97
    Points
    97
    Par défaut
    Excellent, ça fait exactement mon affaire, Merci beaucoup

    J'ai une autre question si ça te dérangerait pas de m'aider la dessus

    imaginant que cette liste de cd ou disque est composée de la façon suivante

    chaque disque a son nom q lang et suivi d'une liste des noms auteurs ex:


    [disque "la nature" 3 Fr ["Albert", "Celine"] disque "la mer" 9 An ["Jean","Michel"] ]

    je voudrais construire une fonction qui prend comme argument une liste

    des disques et me retourneune liste des auteurs seulement , en

    remplaçant chaque disque par la liste de ses auteurs et pour les

    cassettes elle retourne juste le mot 'cassette' , et si un disque n'existe

    pas , elle doit me retourner Nothing


    exemple

    si je fais listeAuteurs [cassette "Musique" 3 fr , disque "la nature" 2 Fr,disque "la mer" 250 Ml] [malistedesdisque]

    elle doit me retourner ["cassette","Albert", "Celine","Jean","Michel"]


    si je fais listeAuteurs ["cassette", disque "la nature" 2 Fr,disque "la mer" 250 Ml,disque "blablabla" 250 Ml]

    elle doit me retourner Nothing


    voilâ ce que j'ai fait et qui me parait trop long, en meme temps je n'arrive pas à faire le test Nothing et Just



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
     
     
     
    listeAuteurs :: [auteur] -> [disque] -> Maybe [auteur]
     
     
    listeAuteurs x recx  =
    --		|existe x recx  == False = Nothing	
    		let d= listeAuteursAux x recx
    			in Just(d)
     
     
    listeAuteursAux [] _ = []
    listeAuteursAux ((disque n q u):xs) rec =
           		 dans (disque n q u) rec ++  listeAuteursAux xs rec
     
     
    -- si l'element est pas un disque
    listeAuteursAux (x:xs) rec = x : listeAuteursAux xs rec   
     
     
    dans :: auteur -> [disque] -> [auteur]
    dans _ [] = []
    dans (disque n q u) (disque n1 _ _ reste :ys)
    	|n == n1  = reste
    	|otherwise = dans (disque n q u) ys

    Merci

  6. #6
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    J'avoue que je ne comprends pas bien ton problème. Pourquoi prends-tu une liste d'auteurs et des disques pour renvoyer une autre liste d'auteurs ?
    Moi j'aurais fait
    listeAuteurs [disque "la nature" 3 Fr ["Albert", "Celine"] disque "la mer" 9 An ["Jean","Michel"] ] renvoie ["Albert", "Celine", "Jean","Michel"]

    En plius tu mélanges des types de données différents, disques et cassettes, c'est volontaire ?
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    311
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2005
    Messages : 311
    Points : 97
    Points
    97
    Par défaut
    en fait c'est un cas général, je l'ai mal représenté , mais voilà une bonne explication


    on considère une liste de Materiel est composée de la façon suivante

    chaque Materiel a son nom qte type qui doit etre (L ou P ou M ) et suivi d'une liste des noms de composants (chaque composant peut etre composantBase ou composant materiel qui est lui aussi est un materiel composé) ex:


    lsiteMateriel = [Materiel "MA" 3 L [ComposantMateriel "MB" 30 P, ComposantBase "C1" 7 P], Materiel "MB" 30 P [ComposantBase "C2" 5 L, ComposantBase "C3" 50 L, ComposantMateriel "MC" 5 L] , Materiel "MC" 1 M [ComposantBase "C4" 5 L, ComposantBase "C5" 40 L, ComposantBase "C6" 15 M ] ]

    ************ Materiel "MB" 30 P [ComposantBase "C2" 5 L, ComposantBase "C3" 50 L, ComposantMateriel "MC" 2 L]

    ************ Materiel "MC" 1 M [ComposantBase "C4" 5 L, ComposantBase "C5" 40 L, ComposantBase "C6" 15 M ]


    alors si je donne cette liste

    [ComposantBase "C1" 7 P, ComposantBase "C2" 7 P, ComposantMateriel "MA" 6 L ]

    il doit me retourner cette liste , juste des composantsbase , en ajustant les qtes


    [ComposantBase "C1" 7 P, ComposantBase "C2" 7 P,
    ComposantBase "C2" 10 L, ComposantBase "C3" 100 L,
    ComposantBase "C4" 10 L, ComposantBase "C5" 80 L, ComposantBase "C6" 30 M,
    ComposantBase "C1" 14 P]



    et s'il trouve un composantMateriel qui n'exite pas dans ma liste de Materiel , il doit retourner Nothing car ça serait une erreur de saisie
    exemple [ComposantMateriel "MZ" 6 L ] je l'ai pas dans ma lsiteMateriel


    je voudrais construire une fonction qui prend comme argument une liste

    des disques et me retourneune liste des auteurs seulement , en

    remplaçant chaque disque par la liste de ses auteurs et pour les

    cassettes elle retourne juste le mot 'cassette' , et si un disque n'existe

    pas , elle doit me retourner Nothing




    exemple

    si je fais listeAuteurs [cassette "Musique" 3 fr , disque "la nature" 2 Fr,disque "la mer" 250 Ml] [malistedesdisque]

    elle doit me retourner ["cassette","Albert", "Celine","Jean","Michel"]


    si je fais listeAuteurs ["cassette", disque "la nature" 2 Fr,disque "la mer" 250 Ml,disque "blablabla" 250 Ml]

    elle doit me retourner Nothing




    j'ai déjà la fonction estComposantBase qui me retourne True s'il s'agit d'un composantBase
    et la fonction estComposantMateriel qui me retourne True s'il s'agit d'un composantMateriel


    voilà le code que j'ai fait, pour les déclarations de types , j'ai pas de probleme avec ça , en suppose qu'ils sont tous déclarés



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
     
    normaliser :: [Composant] -> [Materiel] -> Maybe [Composant]
     
    normaliser [] _ = []
    normaliser xs rec=
    	[x | x <- xs , estComposantBase x ]++
    	normaliser [dans y rec | y <- xs , estComposantMateriel y ] rec 
     
     
    dans :: Composant -> [Materiel] -> [Composant]
    dans _ [] = []
    dans (ComposantMateriel n q u) (Materiel n1 _ _ ing :ys)
    	|n == n1  = ing
    	|otherwise = dans (ComposantMateriel n q u) ys



    et en meme temps je ne sais pas comment introduire le Maybe, (Nothing/Just)
    sachant que si un seul composantMateriel qui n'existe pas dans la liste données il faudrait qu'il me donne Nothing


    Merci beaucoup

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 09/06/2014, 12h34
  2. [Delphi2005]Fonction pour supprimer les doublons?
    Par shell13010 dans le forum Langage
    Réponses: 2
    Dernier message: 11/03/2010, 12h36
  3. Comment trier un tableau pour enlever les doublons ?
    Par MuLog dans le forum Collection et Stream
    Réponses: 1
    Dernier message: 18/03/2009, 20h54
  4. une fonction pour enlever les doublons d'un array
    Par secteur_52 dans le forum Delphi
    Réponses: 1
    Dernier message: 27/06/2006, 13h45
  5. Enlever les doublons en fonction de la date
    Par nicko5959 dans le forum Access
    Réponses: 2
    Dernier message: 10/01/2006, 14h13

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