Tout cela est bien documenté sur les sites Web de référence . Mais si vous ne connaissez pas ces fonctions, vous pouvez facilement faire ce genre de choses à la main:
std::string output;
output.reserve(str.size());// optional, avoids buffer reallocations in the loopfor(size_t i =0; i < str.size();++i)if(str[i]!='a') output += str[i];
N'est-ce pas l'algorithme que vous avez fourni O(n^2)?
jww
@jww: Je suppose que vous parlez du dernier exemple de code et qu'il ns'agit de la longueur de chaîne d'origine. Pour chaque caractère d'entrée, je fais 1 test de caractère O(1)et 0 ou 1 caractère ajouté. L'ajout de caractères O(1)est une quantité suffisante de mémoire réservée ou O(current_length)si un nouveau tampon est alloué. Si vous le faites output.reserve(str.size())avant la boucle, cela ne se produit jamais et vous avez un O(n)coût global . Sinon, de manière asymptotique, je suppose que le coût est O(n . log(n) )dû à la stratégie de réallocation des conteneurs STL.
Antoine
5
J'avais besoin de #include <algorithm>
S Meaden
Bonne réponse. C'est toujours bien si la réponse contient de nombreuses solutions. Pour moi, la solution avec le forest la plus adaptée.
Dmitry Nichiporenko
@DmitryNichiporenko la réponse avec le pour ne peut pas être la plus appropriée. Si vous avez un prédicat ou une sortie non vide, je préfère considérer: output.reserve (str.size () + output.size ()); std :: copy_if (str.begin (), str.end (), std :: back_inserter (sortie), [] (char c) {return predicate (c);});
jimifiki
10
L'algorithme std::replacefonctionne par élément sur une séquence donnée (il remplace donc les éléments par des éléments différents, et ne peut pas le remplacer par rien ). Mais il n'y a pas de caractère vide . Si vous souhaitez supprimer des éléments d'une séquence, les éléments suivants doivent être déplacés et std::replacene fonctionnent pas comme ceci.
Vous pouvez essayer d'utiliser std::remove( avecstd::erase ) pour y parvenir.
stringRemoveChar(string str,char c){string result;for(size_t i =0; i < str.size(); i++){char currentChar = str[i];if(currentChar != c)
result += currentChar;}return result;}
Voilà comment je l'ai fait.
Ou vous pouvez faire comme Antoine l'a mentionné:
Voir cette question
qui répond au même problème. Dans ton cas:
Je suppose que la méthode std: remove fonctionne mais cela posait un problème de compatibilité avec les includes donc j'ai fini par écrire cette petite fonction:
Vous devinez bien. Plutôt que d'écrire le vôtre, mieux vaut découvrir pourquoi vous ne pouvez pas utiliser les en-têtes C ++ standard.
xtofl
Eh bien, c'est une opinion personnelle xtofl, ce n'est pas toujours bon d'utiliser le 3ème code, vous ne savez en fait pas ce qu'il fait ni les performances plutôt que d'écrire ce dont vous avez spécifiquement besoin.
Damien
1
Je comprends ce que tu veux dire. C'est l'humilité qui me pousse à choisir la version qui a été revue, testée, optimisée par des rédacteurs de bibliothèques professionnels à plein temps, plutôt que la mienne. La bibliothèque standard peut être considérée comme une connaissance requise: ses fonctions ainsi que sa complexité d'exécution.
xtofl
À part les chaînes, c'est une solution C à un problème C ++. Je ne pense pas que cela aurait dû être rejeté.
Fondamentalement, chaque fois que je trouve un caractère donné, j'avance le décalage et je déplace le caractère vers l'index correct. Je ne sais pas si c'est correct ou efficace, je commence (encore une fois) au C ++ et j'apprécierais toute contribution à ce sujet.
''
n'est en effet pas un personnage.Réponses:
Fondamentalement,
replace
remplace un caractère par un autre et''
n'est pas un personnage. Ce que vous recherchez, c'esterase
.Voir cette question qui répond au même problème. Dans ton cas:
Ou utilisez
boost
si c'est une option pour vous, comme:Tout cela est bien documenté sur les sites Web de référence . Mais si vous ne connaissez pas ces fonctions, vous pouvez facilement faire ce genre de choses à la main:
la source
O(n^2)
?n
s'agit de la longueur de chaîne d'origine. Pour chaque caractère d'entrée, je fais 1 test de caractèreO(1)
et 0 ou 1 caractère ajouté. L'ajout de caractèresO(1)
est une quantité suffisante de mémoire réservée ouO(current_length)
si un nouveau tampon est alloué. Si vous le faitesoutput.reserve(str.size())
avant la boucle, cela ne se produit jamais et vous avez unO(n)
coût global . Sinon, de manière asymptotique, je suppose que le coût estO(n . log(n) )
dû à la stratégie de réallocation des conteneurs STL.for
est la plus adaptée.L'algorithme
std::replace
fonctionne par élément sur une séquence donnée (il remplace donc les éléments par des éléments différents, et ne peut pas le remplacer par rien ). Mais il n'y a pas de caractère vide . Si vous souhaitez supprimer des éléments d'une séquence, les éléments suivants doivent être déplacés etstd::replace
ne fonctionnent pas comme ceci.Vous pouvez essayer d'utiliser
std::remove
( avecstd::erase
) pour y parvenir.la source
Utilisation
copy_if
:la source
Voilà comment je l'ai fait.
Ou vous pouvez faire comme Antoine l'a mentionné:
la source
Ce code supprime la répétition des caractères, c'est-à-dire que si l'entrée est aaabbcc alors la sortie sera abc.
la source
Au cas où vous auriez un
predicate
et / ou un non videoutput
à remplir avec la chaîne filtrée, je considérerais:Dans la question d'origine, le prédicat est
[](char c){return c != 'a';}
la source
Sur la base d'autres réponses, voici un autre exemple où j'ai supprimé tous les caractères spéciaux dans une chaîne donnée:
Entrée vs sortie:
la source
Je suppose que la méthode std: remove fonctionne mais cela posait un problème de compatibilité avec les includes donc j'ai fini par écrire cette petite fonction:
Utilisez simplement comme
et il supprimera toutes les occurrences de la liste de caractères donnée.
Cela peut également être un peu plus efficace car la boucle revient après la première correspondance, nous faisons donc moins de comparaison.
la source
Voici comment je fais:
Fondamentalement, chaque fois que je trouve un caractère donné, j'avance le décalage et je déplace le caractère vers l'index correct. Je ne sais pas si c'est correct ou efficace, je commence (encore une fois) au C ++ et j'apprécierais toute contribution à ce sujet.
la source
Supprime les majuscules Y et S de str, laissant "ourtring".
Notez qu'il
remove
s'agit d'un algorithme et que l'en-tête doit être<algorithm>
inclus.la source