Sto usando quanto segue:
replace (str1.begin(), str1.end(), 'a' , '')
Ma questo sta dando un errore di compilazione.
Sto usando quanto segue:
replace (str1.begin(), str1.end(), 'a' , '')
Ma questo sta dando un errore di compilazione.
Risposte:
Fondamentalmente, replace
sostituisce un personaggio con un altro e ''
non è un personaggio. Quello che stai cercando èerase
.
Vedi questa domanda che risponde allo stesso problema. Nel tuo caso:
#include <algorithm>
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
Oppure usa boost
se questa è un'opzione per te, come:
#include <boost/algorithm/string.hpp>
boost::erase_all(str, "a");
Tutto questo è ben documentato sui siti web di riferimento . Ma se non conoscessi queste funzioni, potresti facilmente fare questo tipo di cose a mano:
std::string output;
output.reserve(str.size()); // optional, avoids buffer reallocations in the loop
for(size_t i = 0; i < str.size(); ++i)
if(str[i] != 'a') output += str[i];
O(n^2)
?
n
sia la lunghezza della stringa originale. Per ogni carattere di input, eseguo un test di carattere O(1)
e aggiungo 0 o 1 carattere. Il carattere da aggiungere è O(1)
se la memoria è sufficiente o O(current_length)
se viene allocato un nuovo buffer. Se lo fai output.reserve(str.size())
prima del ciclo questo non accade mai e hai un O(n)
costo globale . In caso contrario, in modo asintotico, immagino che il costo sia O(n . log(n) )
dovuto alla strategia di riallocazione del contenitore STL.
for
è la più adatta.
L'algoritmo std::replace
funziona per elemento su una data sequenza (quindi sostituisce elementi con elementi diversi e non può sostituirlo con niente ). Ma non esiste un carattere vuoto . Se vuoi rimuovere elementi da una sequenza, i seguenti elementi devono essere spostati e std::replace
non funziona in questo modo.
Puoi provare a usare std::remove
( insieme astd::erase
) per ottenere questo risultato.
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
string RemoveChar(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;
}
Ecco come l'ho fatto.
Oppure potresti fare come ha detto Antoine:
Vedi questa domanda che risponde allo stesso problema. Nel tuo caso:
#include <algorithm> str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
Questo codice rimuove la ripetizione di caratteri, cioè, se l'input è aaabbcc, l'output sarà abc.
cin >> s;
ans = "";
ans += s[0];
for(int i = 1;i < s.length();++i)
if(s[i] != s[i-1])
ans += s[i];
cout << ans << endl;
Nel caso tu abbia un predicate
e / o un non vuoto output
da riempire con la stringa filtrata, prenderei in considerazione:
output.reserve(str.size() + output.size());
std::copy_if(str.cbegin(),
str.cend(),
std::back_inserter(output),
predicate});
Nella domanda originale il predicato è [](char c){return c != 'a';}
Sulla base di altre risposte, ecco un altro esempio in cui ho rimosso tutti i caratteri speciali in una determinata stringa:
#include <iostream>
#include <string>
#include <algorithm>
std::string chars(".,?!.:;_,!'\"-");
int main(int argc, char const *argv){
std::string input("oi?");
std::string output = eraseSpecialChars(input);
return 0;
}
std::string eraseSpecialChars(std::string str){
std::string newStr;
newStr.assign(str);
for(int i = 0; i < str.length(); i++){
for(int j = 0; j < chars.length(); j++ ){
if(str.at(i) == chars.at(j)){
char c = str.at(i);
newStr.erase(std::remove(newStr.begin(), newStr.end(), c), newStr.end());
}
}
}
return newStr;
}
Ingresso vs uscita:
Input:ra,..pha
Output:rapha
Input:ovo,
Output:ovo
Input:a.vo
Output:avo
Input:oi?
Output:oi
Immagino che il metodo std: remove funzioni ma dava qualche problema di compatibilità con gli include, quindi ho finito per scrivere questa piccola funzione:
string removeCharsFromString(const string str, char* charsToRemove )
{
char c[str.length()+1]; // + terminating char
const char *p = str.c_str();
unsigned int z=0, size = str.length();
unsigned int x;
bool rem=false;
for(x=0; x<size; x++)
{
rem = false;
for (unsigned int i = 0; charsToRemove[i] != 0; i++)
{
if (charsToRemove[i] == p[x])
{
rem = true;
break;
}
}
if (rem == false) c[z++] = p[x];
}
c[z] = '\0';
return string(c);
}
Basta usare come
myString = removeCharsFromString (myString, "abc \ r");
e rimuoverà tutte le occorrenze della lista di caratteri data.
Questo potrebbe anche essere un po 'più efficiente poiché il ciclo ritorna dopo la prima corrispondenza, quindi in realtà facciamo meno confronti.
Ecco come lo faccio:
std::string removeAll(std::string str, char c) {
size_t offset = 0;
size_t size = str.size();
size_t i = 0;
while (i < size - offset) {
if (str[i + offset] == c) {
offset++;
}
if (offset != 0) {
str[i] = str[i + offset];
}
i++;
}
str.resize(size - offset);
return str;
}
Fondamentalmente ogni volta che trovo un dato carattere, avanzo l'offset e riposiziono il carattere nell'indice corretto. Non so se sia corretto o efficiente, sto iniziando (ancora una volta) in C ++ e apprezzerei qualsiasi input in merito.
#include <string>
#include <algorithm>
std::string str = "YourString";
char chars[] = {'Y', 'S'};
str.erase (std::remove(str.begin(), str.end(), chars[i]), str.end());
Rimuoverà la Y e la S maiuscole da str, lasciando "ourtring".
Nota che remove
è un algoritmo e richiede che sia <algorithm>
inclusa l'intestazione .
''
non è davvero un personaggio.