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

C Discussion :

Recherche de prefixes et de motifs


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 69
    Par défaut Recherche de prefixes et de motifs
    Bonjour,

    Je dois écrire 1 fonction recherchant tout d'abord un motif dans une chaîne de caractères et renvoyant la position des occurences.
    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void recherche (char *texte, char *motif) {
      int i,j;
      for (i=0;i<strlen(texte);i++) {
        j=0;
        if (texte[i]==motif[j]) {
          printf("occurrence en position:%d\n",i);
          j=j+1;
        }
        else
          j=j+1;
      }
    }
    Ce code ne prends en compte que le premier caractère du motif pas les autres.
    Par exemple, pour :
    texte = bonjour
    motif = oj
    Il me renvoie seulement :
    occurence en position 1
    Alors que j'incrémente j donc je regarde les autres caractères du motif...
    Que dois-je modifier?

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Par défaut
    Normal, tu compares un caractere ( texte[i] ) et pas une chaine de caractere.

    Utilise la fonction strcmp

    Si tu veux le faire toi même, alors après avoir incrémenté j dans le cas ou les deux caractères sont égaux, il faut que tu regarde le caractère suivant. Tu devrais utiliser une boucle while, avec comme condition :
    tant que le caractere courant de ma chaine (i+j) est égal au caractere courant de mon motif (j), continuer.
    Quand tu arrive à la fin du motif, c'est gagné.
    Attention à ne pas dépasser la longueur du motif et de la chaine.

    C'est clair ?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 69
    Par défaut
    Oui, ok je vais essayer avec tes indications.

    Merci


    EDIT :
    Je crois ne pas bien comprendre exactement ce qu'il faut faire..


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void recherche (char *texte, char *motif) {
      int i,j;
      printf("\n++++ Compte rendu de la recherche d'occurrences dans le motif  ++++\n");
     
      for (i=0;i<strlen(texte);i++) {
        j=0;
        if (texte[i]==motif[j] && j<strlen(motif)) {
          printf("occurrence en position:%d\n",i);
          j=j+1;
        }
        while (texte[i+j]==motif[j] && j<strlen(motif))
          j=j+1;
      }
    }

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    104
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 104
    Par défaut
    Trace ton programme, il y a encore un soucis.

    Tu compares texte[i] et motif[j] dans un if et tu fais le printf("Occurence à l'indice ....").
    C'est à dire que des l'instant que deux lettres sont identiques, tu rentres dans ton if et tu affiches ton message.

    Il te manque au moins une boucle et tu dois déplacer ton printf().

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Par défaut
    Tu n'es pas très loin.
    Le principe est le suivant :
    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
     
    int trouve = 0;
    for (i=0;i<strlen(texte);i++) {
        j=0;
        while ( texte[i+j]==motif[j] )
        {
            j=j+1;
            if( j == strlen(motif) )
            {
                trouve = 1;
                break;
            }
        }
        if( trouve == 1)
           break;
    }
    if(trouve == 1)
        printf("TROUVE !\n");
    Attention je n'ai pas mis de controle de dépassement de longueur.
    Dans le while il faut faire attention a ne pas depasser la taille de motif ET la taille de texte

    Code non testé

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    pour rechercher une sous-chaîne (motif) dans une chaîne la fonction est strstr

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 69
    Par défaut
    Voici le 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
    void recherche (char *texte, char *motif) {
      int i,j, trouve =0;
      for (i=0;i<strlen(texte);i++) {
        j=0;
        while (texte[i+j]==motif[j]) {
          j=j+1;
          if (j==strlen(motif) && j<strlen(texte)) {
    	trouve = 1;
    	break;
          }
        }
        j=j+1;
        if (trouve == 1)
          break;
      }
      if (trouve == 1)
        printf("occurrence en position:%d\n",j);
    }
    Mais il ne marche pas, il ne va pas jusqu'à la fin du motif, alors que j'incrémente j si while est respecté et s'il ne l'est pas. Il me renvoie toujours que la position du premier caractère du motif, et en + pas la bonne position: il commence à compter à 1 et non pas à 0.
    En+, lorsqu'il y a plusieurs fois la lettre comme ici :
    texte = bonjour
    motif = ou
    il renvoie que la position du premier o alors qu'il est répété 2fois... et ne renvoie donc toujours pas u.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Par défaut
    ton j = j+1 a la fin du while ne sert a rien.
    Le debut de ton motif est tout simplement en posision i
    La vérification pour ne pas dépasser la taille doit etre mis avec le while() et non pas dans le if en dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( i+j < strlen(texte) && j < strlen(motif) && texte[i+j]==motif[j])

  9. #9
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void recherche (char *texte, char *motif) {
      char *p=NULL, *p0=NULL ;
      int  i = strlen(motif) ;
     
      p0 = texte ;
     
      while ( (p = strstr ( p0, motif)) != NULL )
      {
           printf("occurrence en position:%d\n",(p-texte));
           p0 = p + i ;
      }
    }

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Par défaut
    Oui, mais ça m'a l'air d'un exercice et je crois qu'il doit créer la fonction lui meme...
    Je me trompe peut etre ceci dit.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 69
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    ton j = j+1 a la fin du while ne sert a rien.
    Le debut de ton motif est tout simplement en posision i
    La vérification pour ne pas dépasser la taille doit etre mis avec le while() et non pas dans le if en dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( i+j < strlen(texte) && j < strlen(motif) && texte[i+j]==motif[j])

    Ok pour le j=j+1 après le while et ok pour les conditions du while.
    Par contre, quand tu dis que le début de mon motif est en position, cela signifie que je dois changer quoi?
    Parce que je l'incrémente, de toute façon, i donc si le début de mon motif est i, il devrait augmenter quand i augmente?

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 69
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void recherche (char *texte, char *motif) {
      char *p=NULL, *p0=NULL ;
      int  i = strlen(motif) ;
     
      p0 = texte ;
     
      while ( (p = strstr ( p0, motif)) != NULL )
      {
           printf("occurrence en position:%d\n",(p-texte));
           p0 = p + i ;
      }
    }
    Merci beaucoup, ce peut-être une autre solution que je pourrais présenter, mais je dois creer ma fonction moi-même.

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Par défaut
    Citation Envoyé par Victoria007 Voir le message
    Ok pour le j=j+1 après le while et ok pour les conditions du while.
    Par contre, quand tu dis que le début de mon motif est en position, cela signifie que je dois changer quoi?
    Parce que je l'incrémente, de toute façon, i donc si le début de mon motif est i, il devrait augmenter quand i augmente?
    L'astuce c'est que si tu trouves le motif, alors tu sort de ta boucle (avec les break).
    Donc la variable i aura à ce moment là la position du début de ton motif.

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 69
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    L'astuce c'est que si trouve == 1, c'est a dire que tu a trouvé le motif, alors tu sort de ta boucle (avec les break).
    Donc la variable i aura à ce moment là la position du début de ton motif.
    Ok mais moi j'veux pas sortir, puisque j'veux étudier tous les caractères de mon motif.

    EDIT: Nan ok, j'ai compris. Trouve = 1, seulement si j'ai étudié tous les caractèrs du motifs puisque j'incrémente j avant de poser cette condition.
    Mais alors pourquoi il regarde que le premier caractère de mon motif? alors que strlen(motif) est supérieur à 1...?

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 69
    Par défaut
    J'ai modifié encore le code et voici que j'obtiens :
    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
    void recherche (char *texte, char *motif) {
      int i,j, trouve =0;
      for (i=0;i<strlen(texte);i++) {
        j=0;
        while (texte[i+j]==motif[j] && j<=strlen(motif) && i+j <strlen(texte)) {
          printf("occurrence en position:%d\n",i);
          j=j+1;
          if (j==(strlen(motif)+1)) {
    	trouve = 1;
    	break;
          }
        }
        if (trouve == 1)
          break;
      }
      /*
      if (trouve == 1)
        printf("again occurrence en position:%d\n",i);
      */
    }
    Ce code me renvoie pour :
    texte = bonjour
    motif = ou
    occurrence en position 1
    occurrence en position 4
    Donc ce qui correspond aux occurrences de o

    Mais ça ne marche tjrs pas pour les autres caractères du motif, alors que pourtant j'incrémente bien j et j'ai changé la condition if en mettant j==(strlen(motif)+1) car en effet, si mon motif fait 2lettres, la taille sera de 1 et donc j doit etre égale à 2 pour sortir de la boucle.
    Comment faire?

    j'ai commenté les 2dernières lignes, car elles ne changent pas le résultat du programme...

  16. #16
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Victoria007 Voir le message
    Merci beaucoup, ce peut-être une autre solution que je pourrais présenter, mais je dois creer ma fonction moi-même.
    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
     
    void recherche (char *texte, char *motif) {
      char *p0=texte ;
      int  i = strlen(motif), j=0 ;
     
      while ( p0 != NULL )
      {
           if ( *p0 == *(motif+j) )
             {
               j = j + 1 ;
               if ( j == i )
                {
                   printf("occurrence en position:%d\n",(p0-texte-i));
                   j= 0 ;
                }
             }
           else
               j = 0 ;
     
           p0 = p0 + 1 ;
      }
    }

  17. #17
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Par défaut
    Citation Envoyé par Victoria007 Voir le message
    J'ai modifié encore le code et voici que j'obtiens :
    j'incrémente bien j et j'ai changé la condition if en mettant j==(strlen(motif)+1) car en effet, si mon motif fait 2lettres, la taille sera de 1 et donc j doit etre égale à 2 pour
    Non ! si ton motif fait 2 lettres la taille (strlen) est 2...
    De plus tes tests pour ne pas dépasser la taille des textes sont faux.
    - Il faut les mettres en début de la condition du while. De cette manière si le test échoue, tu n'essaiera pas de lire texte et motif :

    while ( j<strlen(motif) && i+j <strlen(texte) && texte[i+j]==motif[j] )

    PS : j'essaye de t'aider a faire marcher la méthode que tu avais commencé a trouver toi même dans ton premier post. Celle de souviron est plus efficace, si tu arrive à la comprendre.

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 69
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    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
     
    void recherche (char *texte, char *motif) {
      char *p0=texte ;
      int  i = strlen(motif), j=0 ;
     
      while ( p0 != NULL )
      {
           if ( *p0 == *(motif+j) )
             {
               j = j + 1 ;
               if ( j == i )
                {
                   printf("occurrence en position:%d\n",(p0-texte-i));
                   j= 0 ;
                }
             }
           else
               j = 0 ;
     
           p0 = p0 + 1 ;
      }
    }
    Merci beaucoup souviron pour ton code, j'vais essayer de le comprendre.
    Cependant, en le testant, il me renvoie une erreur de segmentation.. d'où cela peut-il venir?

  19. #19
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    tu peux remplacer le

    par

    sinon je ne vois pas.. A moins que texte ou motif soit NULL..

  20. #20
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 69
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    Non ! si ton motif fait 2 lettres la taille (strlen) est 2...
    De plus tes tests pour ne pas dépasser la taille des textes sont faux.
    - Il faut les mettres en début de la condition du while. De cette manière si le test échoue, tu n'essaiera pas de lire texte et motif :

    while ( j<strlen(motif) && i+j <strlen(texte) && texte[i+j]==motif[j] )

    PS : j'essaye de t'aider a faire marcher la méthode que tu avais commencé a trouver toi même dans ton premier post. Celle de souviron est plus efficace, si tu arrive à la comprendre.
    Oui et c'est super gentil de ta part, si j'arrivais à faire marcher cette méthode sur laquelle je bloque depuis le départ, ce serait génial, celle de souviron serait alors un + que je pourrais également me servir.
    Par contre, j'ai fait les modifications nécessaires je pense que tu m'as indiquer à l'aide de mes erreurs, mais le programme n'incrémente toujours pas les caractèrs du motif, ou du moins il ne me renvoie que les occurences du premier caractère du motif même s'il y en a 2... et franchement, je n'arrive pas à voir pourquoi

Discussions similaires

  1. [WSS3] recherche: pluriels,prefixe,accent,pertinence
    Par sboober dans le forum SharePoint
    Réponses: 12
    Dernier message: 31/03/2009, 15h45
  2. Recherche d'un motif dans une image ?
    Par MonsieurAk dans le forum Windows
    Réponses: 1
    Dernier message: 17/06/2006, 11h39
  3. [RegEx] difficulté à créer un motif de recherche
    Par cyberzoide dans le forum Langage
    Réponses: 3
    Dernier message: 16/11/2005, 18h46
  4. Réponses: 5
    Dernier message: 23/08/2004, 21h12
  5. recherche d'un motif inconnu et de taille inconnu
    Par perlaud dans le forum Modules
    Réponses: 6
    Dernier message: 07/07/2004, 10h04

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