Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
963 connectés 

  FORUM HardWare.fr
  Programmation
  C

  C Racine commune

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

C Racine commune

n°2279632
sined40
Posté le 17-04-2016 à 23:28:19  profilanswer
 

Bonjour,
 
Je suis à la recherché d'une function en C ou d'un algorithme qui permettrait de garder seulement les racines communes dans une liste classé par ordre alphabetique.
J'ai essayé avec un strtok mais sans success.
 
Par exemple: bonjour, bonsoir => racine commune bon
Pour info: MaListe est une variable globale contenant les mots bonjour, bonsoir ... etc
 

Code :
  1. void RootCommon(void)
  2. {
  3.     unsigned int MyLen1, MyLen2, MyLen;
  4.     unsigned int MyFlg;
  5.     unsigned char MyChar1, MyChar2;
  6.     unsigned int MyIdx;   
  7.     unsigned char MyRoot[20];
  8.     // Init.
  9.     MyLen = 0;
  10.     MyLen1 = 0;
  11.     MyLen2 = 0;
  12.     MyFlg = 0;
  13.     MyIndex = 0;
  14.     MyChar1 = 0;
  15.     MyChar2 = 0;
  16.     printf("\n" );
  17.     while (MyFlg == 0)
  18.     {
  19.         MyPtr1 = *(MaListe + MyIndex);
  20.         MyPtr2 = *(MaListe + MyIndex+1);
  21.         MyLen1 = strlen(MyPtr1);
  22.         MyLen2 = strlen(MyPtr2);
  23.         if (MyLen1 > MyLen2)
  24.             MyLen = MyLen2;
  25.         else
  26.             MyLen = MyLen1;
  27.         memset((void*) MyRoot,'\0', sizeof(unsigned char)*20);
  28.         for(MyIdx=0; MyIdx < MyLen; MyIdx++)
  29.         {
  30.             MyChar1 = *(MyPtr1+MyIdx);
  31.             MyChar2 = *(MyPtr2+MyIdx);
  32.             if (MyChar1 != MyChar2)
  33.             {
  34.                 if (strlen((const char*)MyRoot)>0)
  35.                     printf("Racine commune:%s\n",MyRoot);
  36.                 break;
  37.             }
  38.             else
  39.             {
  40.                 MyRoot[MyIdx]=MyChar1;
  41.                 printf(" |_Mot %02d - Lettre %c - Mot %02d - Lettre %c\n",
  42.                         MyIndex, MyChar1, MyIndex+1, MyChar2);
  43.             }
  44.             if (MyIdx == (MyLen-1))
  45.             {
  46.                 memset((void*) MyRoot, '\0', sizeof(unsigned char)*20);
  47.                 printf("  |_Mot %s entierement contenu dans mot %s\n", MyPtr1, MyPtr2);
  48.             }
  49.         }
  50.         printf("\n" );
  51.        
  52.         MyIndex++;
  53.         if ((MyIndex+1) > NbrMot)
  54.             MyFlg = 1;
  55.     }

mood
Publicité
Posté le 17-04-2016 à 23:28:19  profilanswer
 

n°2279644
rat de com​bat
attention rongeur méchant!
Posté le 18-04-2016 à 13:57:18  profilanswer
 

Si tu veux de l'aide c'est toujours bien de faciliter la tâche aux gens en donnant un exemple complet et compilable.
 

Code :
  1. > "gcc" "tst.c" -Wall -O3 -c
  2. tst.c: In function 'RootCommon':
  3. tst.c:13:2: error: 'MyIndex' undeclared (first use in this function)
  4. tst.c:13:2: note: each undeclared identifier is reported only once for each function it appears in
  5. tst.c:16:2: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]
  6. tst.c:16:2: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]
  7. tst.c:19:3: error: 'MyPtr1' undeclared (first use in this function)
  8. tst.c:19:14: error: 'MaListe' undeclared (first use in this function)
  9. tst.c:20:3: error: 'MyPtr2' undeclared (first use in this function)
  10. tst.c:21:3: warning: implicit declaration of function 'strlen' [-Wimplicit-function-declaration]
  11. tst.c:21:12: warning: incompatible implicit declaration of built-in function 'strlen' [enabled by default]
  12. tst.c:27:3: warning: implicit declaration of function 'memset' [-Wimplicit-function-declaration]
  13. tst.c:27:3: warning: incompatible implicit declaration of built-in function 'memset' [enabled by default]
  14. tst.c:53:21: error: 'NbrMot' undeclared (first use in this function)
  15. tst.c:55:1: error: expected declaration or statement at end of input


 
Certes, c'est des choses faciles à corriger, mais bon...
 
Ceci étant, les signed/unsigned char c'est pour des nombres, pour des caractères on utilise simplement char. Pourquoi tu as mis un cast void* dans l'appel de memset()? Et pour strlen() si tu déclares ton MyRoot simplement comme char[] pas besoin de cast non plus (testé avec GCC 4.7.2 -Wall).

n°2279665
rat de com​bat
attention rongeur méchant!
Posté le 18-04-2016 à 20:47:54  profilanswer
 

Bon, je m'ennuais, c'est ce genre de truc dont tu as besoin? A completer...
 

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #define SZ_BUF 20
  4. int main(void)
  5. {
  6.     char *mot1="abcdefghjklhfdsdcpogrdaa";
  7.     char *mot2="abcdefghjklhfdsdcpogrdbb";
  8.    
  9.     char racine[SZ_BUF];
  10.    
  11.     if(strcmp(mot1, mot2)==0)
  12.     {
  13.         printf("(1) et (2) sont identiques\n" );
  14.     }
  15.     else if(strstr(mot1, mot2))
  16.     {
  17.         printf("%s (2) est contenu dans %s (1)\n", mot2, mot1);
  18.     }
  19.     else if(strstr(mot2, mot1))
  20.     {
  21.         printf("%s (1) est contenu dans %s (2)\n", mot1, mot2);
  22.     }
  23.     else
  24.     {
  25.         int i;
  26.         for(i=0;mot1[i]&&mot2[i]&&mot1[i]==mot2[i]&&i<(SZ_BUF-1);i++)
  27.             racine[i]=mot1[i];
  28.         racine[i]='\0';
  29.        
  30.         if(i)
  31.         {
  32.             printf("racine commune: %s\n", racine);
  33.         }
  34.     }
  35.    
  36.     return 0;
  37. }

n°2279793
sined40
Posté le 19-04-2016 à 23:09:35  profilanswer
 

rat de combat a écrit :

Bon, je m'ennuais, c'est ce genre de truc dont tu as besoin? A completer...
 

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #define SZ_BUF 20
  4. int main(void)
  5. {
  6.     char *mot1="abcdefghjklhfdsdcpogrdaa";
  7.     char *mot2="abcdefghjklhfdsdcpogrdbb";
  8.    
  9.     char racine[SZ_BUF];
  10.    
  11.     if(strcmp(mot1, mot2)==0)
  12.     {
  13.         printf("(1) et (2) sont identiques\n" );
  14.     }
  15.     else if(strstr(mot1, mot2))
  16.     {
  17.         printf("%s (2) est contenu dans %s (1)\n", mot2, mot1);
  18.     }
  19.     else if(strstr(mot2, mot1))
  20.     {
  21.         printf("%s (1) est contenu dans %s (2)\n", mot1, mot2);
  22.     }
  23.     else
  24.     {
  25.         int i;
  26.         for(i=0;mot1[i]&&mot2[i]&&mot1[i]==mot2[i]&&i<(SZ_BUF-1);i++)
  27.             racine[i]=mot1[i];
  28.         racine[i]='\0';
  29.        
  30.         if(i)
  31.         {
  32.             printf("racine commune: %s\n", racine);
  33.         }
  34.     }
  35.    
  36.     return 0;
  37. }



 
Bonsoir,
 
Merci pour votre réponse et désolé pour le programme qui ne compile pas, j'ai fait un copier-coller brutal.
Effectivement votre code marche cependant je pense que l'analyse de mon problème n'est pas la bonne.
 
Mon besoin est de pouvoir isoler des termes afin de définir une racine commune
Par exemple; j'ai les mots suivants classés de façon alphabetique donc sans doublon:
- adverb
- adverbial
- adverbially
- adversary
- adverse
- adversity
 
Le résultat que je souhaite obtenir aprés le passage de ma fonction est le suivant:
- adverb car adverb, adverbial et adverbially ont pour racine commune seulement adverb
- advers car adversary, adverse et adversity ont pour racine commune seulement advers
 
C'est là que je commence à bloquer, je ne sais pas comment procéder soit je parcours chaque mot lettre par lettre: la 1ere lettre, la 2e lettre et la 3e lettre et j'isole ...
J'ai repris votre programme et en modifiant les mot1, mot2 en les liant à un tableau contenant mes exemples ... mais sans succès

n°2279794
sined40
Posté le 19-04-2016 à 23:10:38  profilanswer
 

rat de combat a écrit :

Bon, je m'ennuais, c'est ce genre de truc dont tu as besoin? A completer...
 

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #define SZ_BUF 20
  4. int main(void)
  5. {
  6.     char *mot1="abcdefghjklhfdsdcpogrdaa";
  7.     char *mot2="abcdefghjklhfdsdcpogrdbb";
  8.    
  9.     char racine[SZ_BUF];
  10.    
  11.     if(strcmp(mot1, mot2)==0)
  12.     {
  13.         printf("(1) et (2) sont identiques\n" );
  14.     }
  15.     else if(strstr(mot1, mot2))
  16.     {
  17.         printf("%s (2) est contenu dans %s (1)\n", mot2, mot1);
  18.     }
  19.     else if(strstr(mot2, mot1))
  20.     {
  21.         printf("%s (1) est contenu dans %s (2)\n", mot1, mot2);
  22.     }
  23.     else
  24.     {
  25.         int i;
  26.         for(i=0;mot1[i]&&mot2[i]&&mot1[i]==mot2[i]&&i<(SZ_BUF-1);i++)
  27.             racine[i]=mot1[i];
  28.         racine[i]='\0';
  29.        
  30.         if(i)
  31.         {
  32.             printf("racine commune: %s\n", racine);
  33.         }
  34.     }
  35.    
  36.     return 0;
  37. }



 
Bonsoir,
 
Merci pour votre réponse et désolé pour le programme qui ne compile pas, j'ai fait un copier-coller brutal.
Effectivement votre code marche cependant je pense que l'analyse de mon problème n'est pas la bonne.
 
Mon besoin est de pouvoir isoler des termes afin de définir une racine commune
Par exemple; j'ai les mots suivants classés de façon alphabetique donc sans doublon:
- adverb
- adverbial
- adverbially
- adversary
- adverse
- adversity
 
Le résultat que je souhaite obtenir aprés le passage de ma fonction est le suivant:
- adverb car adverb, adverbial et adverbially ont pour racine commune seulement adverb
- advers car adversary, adverse et adversity ont pour racine commune seulement advers
 
C'est là que je commence à bloquer, je ne sais pas comment procéder soit je parcours chaque mot lettre par lettre: la 1ere lettre, la 2e lettre et la 3e lettre et j'isole ...
J'ai repris votre programme et en modifiant les mot1, mot2 en les liant à un tableau contenant mes exemples ... mais sans succès

n°2279809
h3bus
Troll Inside
Posté le 20-04-2016 à 10:22:20  profilanswer
 

Je fais ce genre de chose avec un arbre n-aire. (eg: http://www.chambily.com/recursivite/chap_VII_4.htm )

 

Bon ça peut sembler énorme à mettre en place pour ce que tu veux faire, mais c'est très puissant!


Message édité par h3bus le 20-04-2016 à 10:22:38

---------------
sheep++
n°2279810
gilou
Modérateur
Modzilla
Posté le 20-04-2016 à 10:27:42  profilanswer
 

Certes, mais c'est pas ça qui va donner les racines. Il lui faut une heuristique pour déterminer quand on considère que la terminaison d'un mot ne fait plus partie de la racine commune, et pour le moment, je n'ai pas vu qu'il en propose une.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2279819
h3bus
Troll Inside
Posté le 20-04-2016 à 11:58:42  profilanswer
 

Effectivement, il faut un critère.
 
Je m'ennuyais donc j'ai fait un exemple en python

Code :
  1. class Wordstree():
  2.     def __init__(self, word="" ):
  3.         self.children = {}
  4.         self.isword = False
  5.        
  6.         if len(word) == 0:
  7.             self.value = ''
  8.            
  9.         else:
  10.             self.value = word[0]
  11.            
  12.             if len(word) > 1:
  13.                 self.children[word[1]]= Wordstree(word[1:])
  14.             else:
  15.                 self.isword = True
  16.    
  17.     def append(self, word):
  18.         if len(word) == 0:
  19.             return
  20.            
  21.         elif word[0] in self.children:
  22.             self.children[word[0]].append(word[1:])
  23.        
  24.         else:
  25.             self.children[word[0]] = Wordstree(word)
  26.        
  27.         if len(word) == 1:
  28.             self.isword = True
  29.    
  30.     def isRoot(self):
  31.         return len(self.children) > 1
  32.    
  33.     def getChildRoots(self, root="" ):
  34.         roots = []
  35.        
  36.         if self.isRoot():
  37.             for key in self.children.iterkeys():
  38.                 roots += [root+self.value+key]
  39.            
  40.         for key, value in self.children.iteritems():
  41.             roots += value.getChildRoots(root + self.value)
  42.        
  43.         return roots
  44. words = [
  45.     "adverb",
  46.     "adverbial",
  47.     "adverbially",
  48.     "adversary",
  49.     "adverse",
  50.     "adversity"
  51.     ]
  52. tree = Wordstree();
  53. for word in words:
  54.     tree.append(word)
  55. print tree.getChildRoots()


 
Résultat:

Code :
  1. >python wordtree.py
  2. ['advers', 'adverb', 'adversa', 'adversi', 'adverse']


---------------
sheep++
n°2279823
rat de com​bat
attention rongeur méchant!
Posté le 20-04-2016 à 14:30:02  profilanswer
 

sined40 a écrit :

Effectivement votre code marche cependant je pense que l'analyse de mon problème n'est pas la bonne.


Je me disais bien que c'était trop facile... Désolé, je sèche...


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  C Racine commune

 

Sujets relatifs
C : Envoi et retour d'un tableau dans des fonctions.[C#]Problème de droit d'accès, Outil de recherche
Les meilleurs livres pour un novice total en C++ ?LANGAGE C : MAC FLOODING
Traduction d'un programme C en pythonOù, comment et sur quel OS apprendre le C++ ?
pistes pour traduction code écrit en C en pythonexerice langage C a resoudre
[C / C#] Exécuter un fichier C sans le compiler[Qt][QML] QObject du C++ vers le QML: gestion mémoire
Plus de sujets relatifs à : C Racine commune


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR