2010-10-31 11 views
0

Je voulais écrire un code qui supprimerait un caractère donné d'une chaîne. Je suis venu avec l'extrait suivant. Maintenant, alors que cela fait mon travail, cela me donne la complexité du pire cas de O (n^2). Quelqu'un peut-il m'aider à améliorer cela.Supprimer un caractère d'une chaîne

#include<iostream.h> 
#include<conio.h> 
#include<stdio.h> 

void Push(char *, int i); 

int n=6; 

int main() 
{ 
clrscr(); 
char *p = "helelo"; 
char delChar = 'e'; 

for(int i=0;i<5;i++) 
{ 
    if(*(p + i) == delChar) 
    { 
    Push(p, i); 
    } 
} 
cout<<p<<endl; 
getch(); 
return 1; 
} 

void Push(char *p, int i) 
{ 
for(int k=i;k<n;k++) 
{ 
    *(p + k) = *(p+k+1); 
} 
} 

Merci

+0

vous devez marcher à travers la liste une fois, et quand vous trouvez le caractère w Pour supprimer, parcourez la liste à partir de ce point mais copiez l'élément suivant dans le courant comme vous le faites. Aussi, pourquoi n'utilisez-vous pas les tableaux 'std :: string'/char, ne faites pas' p [k] 'au lieu de l'indexation manuelle, et renvoyez 1 (0 est un succès)? – GManNickG

Répondre

4
#include <cstring> 
#include <algorithm> 
#include <iostream> 

int main() { 
    using namespace std; 

    char s[] = "helelo"; 
    cout << s << '\n'; 

    char *end = s + strlen(s); 
    end = remove(s, end, 'e'); 
    *end = '\0'; 
    cout << s << '\n'; // hllo 

    return 0; 
} 

Notez que vous ne pouvez pas modifier les littéraux de chaîne, donc j'utilisé un tableau de caractères. Une chaîne std :: serait encore plus facile.

Si vous voulez comprendre comment std :: supprimer des œuvres, le char * instanciation (car il est un modèle) serait, pour le garder simple, regarder quelque chose comme:

char* remove(char *begin, char *end, char value) { 
    char *next = begin; 
    for (; begin != end; ++begin) { 
    if (*begin != value) { 
     *next++ = *begin; 
    } 
    } 
    return next; 
} 
+0

Il n'est pas garanti qu'un 'std :: string' soit terminé par NUL. Donc je suppose que 'std :: string s =" helelo "; * std :: remove (s.begin(), s.end(), 'e') = '\ 0'' ne marchera pas. –

+1

@Prasoon: En fait, 0x change de chaîne dans cette zone, mais je ne me souviens pas de tous les détails exacts. Cependant, avec une chaîne std :: string, vous utilisez plutôt la méthode erase, tout comme vous utilisez s.length() au lieu de strlen. :) –

0

Une idée est de construire une nouvelle chaîne de la première en utilisant uniquement des caractères valides (ceux différents du caractère non désiré), puis initialiser la première chaîne avec celui construit.

0

Quelque chose comme ça devrait le faire :

char *p = "helelo"; 
char delChar = 'e'; 
int len = strlen(p); 

for(int j=0, int i=0;i<len;i++) 
{ 
    if(*(p + i) != delChar) 
    { 
    *(p+j)=*(p+i); 
    ++j; 
    } 
} 
*(p+j)='\0'; 

cout<<p<<endl; 
getch(); 
return 1; 
0

Que diriez-vous:

int main() { 
    clrscr(); 
    char *p = "helelo"; 
    char delChar = 'e'; 

    int k=0; 
    for(int i=0; *(p+i); i++) { 
    if(*(p + i) != delChar) { 
     *(p + k++) = *(p + i); 
    } 
    } 
    *(p + k) = '\0'; 
    cout<<p<<endl; 
    getch(); 
    return 1; 
} 
Questions connexes