Programme c qui supprime les répétitions de caractére identique

Fermé
jihane-se Messages postés 6 Date d'inscription mardi 2 février 2016 Statut Membre Dernière intervention 3 mars 2016 - 2 févr. 2016 à 16:41
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 5 févr. 2016 à 23:36
Salut à tous
svp j'ai besoin votre aides svp je veux faire un programme c qui supprime d'une chaine de caractére les répétions de caractéres consécutifs.par exemple remplacer la chaine AAAABBCCC par ABC
MERCII bcp !!

3 réponses

gardiendelanuit Messages postés 1769 Date d'inscription jeudi 20 décembre 2007 Statut Membre Dernière intervention 19 novembre 2016 264
2 févr. 2016 à 17:03
Bonjour,

Je t'invite à regarder de ce côté https://stackoverflow.com/questions/779875/what-function-is-to-replace-a-substring-from-a-string-in-c

De nombreuses possibilités sont présentes, mais que je sache, il n'y a pas de fonction native en C qui soit pour ce besoin.
0
jihane-se Messages postés 6 Date d'inscription mardi 2 février 2016 Statut Membre Dernière intervention 3 mars 2016
2 févr. 2016 à 17:10
Ok merciii bcp à votre réponse :)
0
[Dal] Messages postés 6057 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 17 mars 2023 1 043
2 févr. 2016 à 17:33
cette question sur SO ne répond pas à la question "Comment supprimer d'une chaine de caractére les répétions de caractéres consécutifs", mais "Comment remplacer, dans une chaîne, une sous-chaîne par une autre".

Dal
0
gardiendelanuit Messages postés 1769 Date d'inscription jeudi 20 décembre 2007 Statut Membre Dernière intervention 19 novembre 2016 264 > [Dal] Messages postés 6057 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 17 mars 2023
2 févr. 2016 à 17:43
Oui c'est ce que j'ai d'ailleurs signalé. J'ai préféré prendre la question du corps du topic :D
0
[Dal] Messages postés 6057 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 17 mars 2023 1 043
2 févr. 2016 à 17:39
Salut jihane-se,

Tu peux passer par une autre chaîne ayant au moins la taille de la chaîne de départ, et où tu copies les caractères non consécutifs jusqu'au caractère '\0'.


Dal
0
jihane-se Messages postés 6 Date d'inscription mardi 2 février 2016 Statut Membre Dernière intervention 3 mars 2016
2 févr. 2016 à 19:31
Salut Dal
Mercii à toi :D
j'essai de faire ce programme mais je ne c'est pas est ce qu'il est juste

#include <stdio.h>
void main()
{
char txt[20];
int L,i,j;
L=strlen(txt);
for(i=0;i<L;i++)
for(j=i+1;j<L;j++)
if(txt[i]==txt[j])
txt[i]=txt[j];

}
svp repondez moi est ce qu'il est juste car je suis encore débutante en programmation :))
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 816 > jihane-se Messages postés 6 Date d'inscription mardi 2 février 2016 Statut Membre Dernière intervention 3 mars 2016
2 févr. 2016 à 22:59
Bonjour,

void main()
Le bon prototype est : int main(void).
De plus, il ne faut pas oublier le return 0; en fin de main().

Dans ton code, il manque la lecture de la variable txt. Par exemple : scanf("%19s", txt);

Ensuite, ton programme ne gère par les lettres consécutives, juste les lettres doublons.
Il faut copier uniquement les caractères lorsque le caractère est différent du précédent (txt[i] != txt[i-1]). Et une seule boucle for suffit.


Merci pour la prochaine fois d'utiliser la balise <code c>.
Exemple :
<code c>ici tu mets ton code</code>
0
jihane-se Messages postés 6 Date d'inscription mardi 2 février 2016 Statut Membre Dernière intervention 3 mars 2016 > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
3 févr. 2016 à 00:06
Boonjour fiddy
Mercii à votre reponse,donc d'aprés vous le programme doit étre comme ceci:

#include <stdio.h>
void main()
{
char txt[20];
int L,i,j;
L=strlen(txt);
for(i=0;i<L;i++)
if(txt[i]!=txt[i+1])
txt[i]=txt[i+1];

}
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 816 > jihane-se Messages postés 6 Date d'inscription mardi 2 février 2016 Statut Membre Dernière intervention 3 mars 2016
3 févr. 2016 à 08:17
Tu as pris en compte la moitié de mes remarques.
Je te laisse donc relire mon poste. Pour la balise, c'est code c. Et non code tout court.

Tu as mal géré les conditions aux limites. Imagine lorsque i=L-1 ce que donnera ton if...

Ensuite il faut copier à partir de 0 à l'indice j (oui il faut une autre variable).
0
[Dal] Messages postés 6057 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 17 mars 2023 1 043
Modifié par [Dal] le 3/02/2016 à 16:43
@jihane-se :
Si on fait une opération destructive, on n'a pas besoin d'une autre chaîne comme je le disais, mais juste de deux pointeurs sur char qui vont parcourir la chaîne, l'un servant à lire les caractères et vérifier s'ils sont répétés consécutivement, et l'autre servant à écrire au bon endroit les caractères écrasant les anciens. Chaque pointeur est incrémenté selon son rôle jusqu'à la lecture et écriture du '\0' final.

Bien sûr, on peut le faire aussi avec deux indices sur le même tableau. Je suppose que c'est vers cette solution que fiddy essaye de te guider.

Par ailleurs, on n'est pas obligé d'exécuter strlen, qui est une perte de temps car cette fonction doit parcourir toute la chaîne jusqu'au '\0', or c'est précisément ce que tu dois faire ensuite... Tu peux donc juste tester si tu rencontres '\0' à l'occasion du traitement de ta chaîne.


Dal
0
jisisv Messages postés 3645 Date d'inscription dimanche 18 mars 2001 Statut Modérateur Dernière intervention 15 janvier 2017 947
Modifié par jisisv le 4/02/2016 à 07:00
Ceci devrait t'inspirer:
   
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

 int unrepeat(const char *src, char *dest)
 {
   char *d;
   int i, l, r;

   d = dest;
   r = 0;

   l = strlen(src);

   for ( i = 0 ; i < l ; i++)
     {
       if ( src[i +1 ] != src[i] )
	 {
	   *d = *(src + i);
	   d++ ;
	   r++;
	 }
     }
   *d = 0;
   return r;
 }     
 
int main(int argc, char *argv[])
{
  char *dest;
  int nc ; 
  if( argc > 1 )
    {
      dest = malloc(strlen(argv[1]) +1) ;

      if ( NULL != dest )
	{
	  //in place modification
	  //dest = argv[1];
   
	  printf("Old string: %s\n", argv[1]);
	  nc  = unrepeat(argv[1], dest);
	  printf("New string %s\n%d\n", dest, nc);
	  return EXIT_SUCCESS;
	}
    }
  return EXIT_FAILURE;
}


Gates gave ^W  sold  you the windows.
GNU gave us the whole house.(Alexandrin)
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 816
3 févr. 2016 à 21:25
Bon, beh, tu as tout dit.

Quelques remarques quand même sur le code pour que jihane-se puisse finaliser le code.

Pour éviter d'utiliser strlen() plusieurs fois, tu peux le mettre dans une variable et passer la taille en argument de unrepeat().

Les conditions aux limites ne marchent pas non plus :-).
Et enfin, il manque un return à la fin du main() cas où argc==1.
0
jisisv Messages postés 3645 Date d'inscription dimanche 18 mars 2001 Statut Modérateur Dernière intervention 15 janvier 2017 947
Modifié par jisisv le 4/02/2016 à 06:53
Il est normal de devoir utiliser strlen deux fois. On pourrait faire un test sur la valeur de src[i+1] , mais j'ai écarté cela dans un but de clarté et de pédagogie.
Le strlen du main est "incontournable" pour malloc. Il n'y a aucune raison d'utiliser une variable globale.

Pour le return , tu as raison. Le code a été corrigé.
As-tu un exemple de bug pour les conditions aux limites ?
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 816
4 févr. 2016 à 22:40
Salut jisisv,

Qui a parlé de variable globale ? Je parle d'une variable locale que tu envoies en argument de unrepeat().
Exemple :
<code c>
if (argc > 1) {
int taille = strlen(argv[1]);
char *dest = malloc(taille+1) ;

if (dest != NULL) {
int nc = unrepeat(argv[1],test, taille);
...
}

Ainsi dans unrepeat(), tu as la taille directement. En plus, tu as dit toi-même :
on n'est pas obligé d'exécuter strlen, qui est une perte de temps car cette fonction doit parcourir toute la chaîne jusqu'au '\0'
Ici encore, dans ta fonction unrepeat() tu peux l'éviter.

Non pas de bugs... C'est juste dommage de faire une itération supplémentaire inutile.
0
[Dal] Messages postés 6057 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 17 mars 2023 1 043
5 févr. 2016 à 15:51
@fiddy : ce n'est pas jisisv qui a dit "Par ailleurs, on n'est pas obligé d'exécuter strlen, qui est une perte de temps car cette fonction doit parcourir toute la chaîne jusqu'au '\0', or c'est précisément ce que tu dois faire ensuite... Tu peux donc juste tester si tu rencontres '\0' à l'occasion du traitement de ta chaîne.", c'est moi :-)

Dal
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 816 > [Dal] Messages postés 6057 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 17 mars 2023
5 févr. 2016 à 23:36
Gloups. Je retire ce paragraphe alors :-).
0