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 :

[ DEBUTANT ] Problème exercice boucle + récursive


Sujet :

Caml

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2007
    Messages : 36
    Points : 7
    Points
    7
    Par défaut [ DEBUTANT ] Problème exercice boucle + récursive
    Bonjour. J'ai un petit exercice à faire que je ne comprends pas très bien. Je ne viens pas là avec le but d'avoir le corrigé, mais je veux comprendre.
    Voici l'énoncé :
    Ecrire, en utilisant une boucle, puis de façon récursive une fonction premiereOccurence :
    char -> string -> int qui détermine le rang de la première occurence du caractere c dans la chaine s. La fonction renverra un message si le caractère n'appartient pas à la chaine.
    Alors déjà en français, qu'est ce qu'une occurence ? J'ai cherché, d'après ce que j'ai compris dans ma situation, c'est tout simplement le première caratcère c que je cherche. Et je veux en résultat un entier qui m'indique la place de c dans s par un numéro.

    J'ai déjà fait une fonction estdans qui me dit si c est dans s ou pas. Alors je pense pouvoir m'en servir.

    Genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    let premiereOccurence c s = 
    if estdans c s = false then print_string " Le caractère n'est pas dans la chaîne " 
    else  ?

    Mais ça n'est pas une boucle...Vu que je suis en vacances je n'ai pas les corrigés de mes quelques autres exercices, donc je n'ai aucun appui pour m'aider....

  2. #2
    alex_pi
    Invité(e)
    Par défaut
    La première occurence d'un caractères c dans une chaine s est le premier entier i tel que s.(i) = c.

    Si tu as fait une fonction permettant de savoir si un caractère est dans une chaîne, il est trivial à modifier. Au lieu de retourner vrai ou faux, tu retournes la position à laquel tu l'as trouvé.

    Have fun

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2007
    Messages : 36
    Points : 7
    Points
    7
    Par défaut
    oulalala..je ne comprends pas tout. Genre je mets premiereOccurence `o` "bonjour" et ça me renvoie 2 ?

  4. #4
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par arnaud405 Voir le message
    oulalala..je ne comprends pas tout. Genre je mets premiereOccurence `o` "bonjour" et ça me renvoie 2 ?
    Plutôt 1 parce que généralement on numérote à partir de 0, mais oui :-)
    b -> 0
    o -> 1
    n -> 2
    j -> 3
    u -> 5
    r -> 6

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2007
    Messages : 36
    Points : 7
    Points
    7
    Par défaut
    ok...Mais comment faire cela avec une boucle...Je viens de débuter en CamL....

  6. #6
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par arnaud405 Voir le message
    ok...Mais comment faire cela avec une boucle...Je viens de débuter en CamL....
    Tu peux nous donner ta fonction qui teste l'appartenance ?

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2007
    Messages : 36
    Points : 7
    Points
    7
    Par défaut
    alors c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    let rec estdans = function c -> function
    " " -> false |
    s  -> if s.[0] = c then true 
    else let n = string_length s in
     estdans c (sub_string s 1 (n-1) ) ;;
    mais je ne comprends pas tout non plus dans cette fonction...

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2007
    Messages : 36
    Points : 7
    Points
    7
    Par défaut
    aïe aïe...aidez moi s'il vous plait..Il faudrait que j'ai compris pour ce week-end...

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 55
    Points : 115
    Points
    115
    Par défaut
    Salut.
    Donc, si je comprends bien, ta fonction devra etre du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #premiereOccurence 'o' "bonjour";;
    - : int = 1
     
    #premiereOccurence 'j' "bonjour";;
    - : int = 3
     
    #premiereOccurence 'a' "bonjour";;
    Exception failure : "Pas d'occurence"
    Donc, tu veux savoir en quelle position apparait le caractere premier argument dans la chaine deuxieme argument... (en commencant par 0)

    Pour celà, effectivement, une fonction recursive s'y prete bien.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let rec premiereOccurence c chaine =
     let n = String.length chaine
     in if (c=chaine.[0]) 
         then 0
         else let sousChaine = String.sub chaine 1 n-1
                  in 1+(premiereOccurence c sousChaine)
    En gros, si le premier caractere de la chaine est le bon, ca renvoie 0, sinon, ca renvois 1+le resultat de cette meme fonction sur la chaine privée de son premier caractere....
    C'est le principe de la recursivité!
    Attention, ici, le cas ou le caractere n'apparait pas dans la chaine n'est pas traité. a toi de le faire en renvoyant une exception, ou un " failwith "Absent" "

    Toujours si j'ai bien compris, tu dois aussi faire une version boucle, c à d, sans recursivité.

    Aussi, peu importe, mais cette fonction existe deja dans la libraire standard de caml :
    http://caml.inria.fr/pub/docs/manual...ef/String.html

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2007
    Messages : 36
    Points : 7
    Points
    7
    Par défaut
    ok..Je te remercie pour ces résultats. Malheureusement je n'ai pas tout compris...Déjà je suis d'accord avec toi pour les réponses que devrait m'envoyer CamL....Je pense que cete fonction doit bien me donner ça...
    en essayant ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let rec premiereOccurence c s =
     let n = string_length s in
     if (c=s.[0]) 
         then 0
         else let ss = string_sub s 1 n-1
                  in 1+(premiereOccurence c ss);;

    il me dit qu'il ne connait pas string_sub....

    Je ne connais pas failwith...
    Merci encore pour ton aide...

  11. #11
    alex_pi
    Invité(e)
    Par défaut
    Ce n'est définitivement pas une bonne idée de prendre la sous chaine pour la passer en argument récursif ! La construction d'une nouvelle chaine est un évènement lourd. Il faut au contraire passer la nouvelle position dans la chaine à laquelle tu te trouves. Une chaine de caractère n'est pas une liste ! Lui retirer son premier élément coute cher, acceder de façon direct au n-ieme élément ne coute rien (c'est un tableau de caractères).

    Donc pour la boucle while, tu fais varier un compteur de 0 à la longueur de la chaine tant que tu n'as pas trouvé ton caractère

    Pour la version récursive, tu appelles récursivement une fonction qui regarde si le caractère désigné par son argument correspond à celui que tu cherches. Si oui, tu retournes l'argument, sinon, tu passes à la case suivante.

    Dans les deux cas, attention aux accès hors chaine.

    Bon courage

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2007
    Messages : 36
    Points : 7
    Points
    7
    Par défaut
    aie aie aie..vous me parlez en Japonnais là...Je n'ai pas vu la boucle while encore... j'ai vu for i=... to ... do ... .
    mais je ne l'ai utilisé qu'une fois....

  13. #13
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par arnaud405 Voir le message
    aie aie aie..vous me parlez en Japonnais là...Je n'ai pas vu la boucle while encore... j'ai vu for i=... to ... do ... .
    mais je ne l'ai utilisé qu'une fois....
    Faire une recherche de premier caractère avec une boucle for, c'est débile, puisqu'on ne sait pas jusqu'où aller ! Et ce serait un peu absurde d'aller jusqu'au bout si c'est le premier caractère, et peu dans la philosophie de lancer une exception (et si tu n'as pas vu les while, je pense que les exceptions peuvent attendre.)

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 55
    Points : 115
    Points
    115
    Par défaut
    plusieurs chose...
    Effectivement, je suis tres habitué aux listes, et ca ne doit pas etre une bonne chose pour les string...

    pour string_sub, il faut utiliser " String.sub" avec une majuscule et un point.

    Sinon, les whiles, c'est pas tellement dans la philosophie fonctionelle si?

    Et c'est pas ce qu'on apprends en premier je pense...
    Enfin...

    Sinon, ta fonction doit renvoyer un entier n'est ce pas...?
    Donc tu peux pas, dans certains cas renvoyer un entier, et dans d'autres afficher un message d'erreur...
    Enfin, si tu peux, mais grace au failwith
    Par exemple, un fonction qui sert a rien hein!

    elle renvoie l'entier naturel non nul inferieur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    let fonctionQuiSertARien = fun x -> 
     if (x> 0) then x-1 else failwith "n'existe pas"
    ca donnera :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #fonctionQuiSertARien 3;;
    - : int = 2
     
     
    #fonctionQuiSertARien 1;;
    - : int = 0
     
     
    #fonctionQuiSertARien 0;;
    Exception failure : "n'existe pas"
    Voilà, le failwith...
    Bon courage

  15. #15
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2007
    Messages : 36
    Points : 7
    Points
    7
    Par défaut
    ok...j'ai compris le failwith.C'est pour sortir du programme avec un message d'erreur ou d'avertissement plutôt. Mais comment je mets ça en prratique..En gros, est il possible que vous m'avanciez pour le code ? mon but n'étant pas de "pomper" ce que vous aller me mettre, mais juste m'aider à comprendre, apprendre, tout en le prouvant...
    Merci beaucoup de vous occuper de moi, mon problème. L'informatique est géniale pour ça. Cet esprit de communauté, de communication, c'est génial. Je le retrouve dans le programmation. Je m'y sens comme dans le monde du libre ( je suis linuxien).

  16. #16
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Citation Envoyé par arnaud405
    Merci beaucoup de vous occuper de moi, mon problème. L'informatique est géniale pour ça. Cet esprit de communauté, de communication, c'est génial. Je le retrouve dans le programmation. Je m'y sens comme dans le monde du libre ( je suis linuxien).
    Attention, Linux et le monde du libre, c'est pas les Bisounours et les sept nains !

    Si j'avais été de mauvaise humeur et que ta remarque ne m'ait pas fait rire, je t'aurais balancé un superbe

    R.T.F.M.
    Read The Fucking Manual

    Trop de gens se trompent en venant du côté du monde libre en croyant que c'est le paradis sur Terre, une sorte de monde à la Alice au Pays des Merveilles où ils sont tous beaux et gentils... Ce monde contient, lui aussi, ses inconvénients, ses contradictions, ses tensions et ses luttes de chefs à trois balles. Entre autres, les pro BSD (gorgonite ?) et les pro GNU n'arrivent toujours pas à s'entendre, ou alors, ce sont les GNU qui ne s'entendent pas avec les BSD... Tu te rends compte, même pour le choix du nom (Linux vs GNU/Linux) il y a des querelles qui font rage, même si l'affaire a déjà été tranchée !

    Il n'y a rien de méchant dans ce post-ci (je préfère préciser, au cas où...).

    Pour en revenir à la question de départ, tu dois mettre ton

    à l'endroit de la fonction où tu détectes une erreur. Si tu fais les choses petit à petit, cet endroit-là, tu devrais le repérer sans trop de difficultés. Il n'y a rien de magique là-dedans.
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

  17. #17
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 55
    Points : 115
    Points
    115
    Par défaut
    oulàlà.... il a pas l'air vaillant ton caml... !

  18. #18
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Je ne comprends pas ta remarque, mais c'est pas grave.

    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
     
    let premiere_occurence c s =
        (let n = String.length s in
     
        let rec auxiliaire i =
            (if (i < n) then
                (if (s.[i] = c) then
                    i
                else
                    auxiliaire (i + 1))
            else
                failwith "Erreur: le caractere n'est pas dans la chaine")
     
        in
     
        auxiliaire 0)
    Ca va mieux comme ça ?

    Désolé, mais pour une fonction aussi simple, je pouvais pas faire un code à trous.
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

  19. #19
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 55
    Points : 115
    Points
    115
    Par défaut
    ma remarque est rapport a ton avatar

  20. #20
    Candidat au Club
    Inscrit en
    Novembre 2007
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    bonsoir, je suis novice en caml et je ne comprend pas pourquoi cette fonction,
    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
    let premiere_occurence c s =
        (let n = String.length s in
     
        let rec auxiliaire i =
            (if (i < n) then
                (if (s.[i] = c) then
                    i
                else
                    auxiliaire (i + 1))
            else
                failwith "Erreur: le caractere n'est pas dans la chaine")
     
        in
     
        auxiliaire 0)
    fonctionne avec ocaml et pas caml light, car voici la reponse caml light

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Toplevel input:
    >    let n = String.length s in
    >            ^^^^^^^^^^^^^
    The label length is unbound.

    pourriez vous me donner le code caml light ?merci

Discussions similaires

  1. Réponses: 2
    Dernier message: 28/08/2006, 13h16
  2. [debutant] clonage en boucle
    Par kokoboy dans le forum Langage
    Réponses: 5
    Dernier message: 24/05/2004, 12h55
  3. [Debutant] Batch et Boucle for
    Par ludovic.fernandez dans le forum Scripts/Batch
    Réponses: 8
    Dernier message: 06/05/2004, 19h21
  4. [debutant]Problèmes
    Par BibiGmi dans le forum OpenGL
    Réponses: 2
    Dernier message: 05/03/2004, 14h00
  5. [Debutant] Problème du linker [Dev-c++4]
    Par Macdir dans le forum Dev-C++
    Réponses: 3
    Dernier message: 30/05/2003, 20h50

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