Estoy usando lo siguiente:
replace (str1.begin(), str1.end(), 'a' , '')
Pero esto está dando un error de compilación.
Estoy usando lo siguiente:
replace (str1.begin(), str1.end(), 'a' , '')
Pero esto está dando un error de compilación.
Respuestas:
Básicamente, replace
reemplaza un personaje por otro y ''
no es un personaje. Lo que estás buscando es erase
.
Vea esta pregunta que responde al mismo problema. En tu caso:
#include <algorithm>
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
O use boost
si esa es una opción para usted, como:
#include <boost/algorithm/string.hpp>
boost::erase_all(str, "a");
Todo esto está bien documentado en sitios web de referencia . Pero si no conociera estas funciones, podría hacer fácilmente este tipo de cosas 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
es la longitud de la cadena original. Para cada carácter de entrada, hago una prueba de O(1)
1 carácter y agrego 0 o 1 carácter. La adición de caracteres es si O(1)
hay suficiente memoria reservada o O(current_length)
si se asigna un nuevo búfer. Si lo hace output.reserve(str.size())
antes del ciclo, esto nunca sucede y tiene un O(n)
costo global . De lo contrario, de forma asintótica, supongo que el costo se O(n . log(n) )
debe a la estrategia de reasignación de contenedores STL.
for
es la más adecuada.
El algoritmo std::replace
funciona por elemento en una secuencia dada (por lo que reemplaza elementos con elementos diferentes y no puede reemplazarlo con nada ). Pero no hay un carácter vacío . Si desea eliminar elementos de una secuencia, los siguientes elementos deben moverse y std::replace
no funciona así.
Puede intentar usar std::remove
( junto constd::erase
) para lograr esto.
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;
}
Así es como lo hice.
O podrías hacer lo que Antoine mencionó:
Vea esta pregunta que responde al mismo problema. En tu caso:
#include <algorithm> str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
Este código elimina la repetición de caracteres, es decir, si la entrada es aaabbcc, la salida será 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;
En caso de que tenga un predicate
y / o un no vacío output
para llenar con la cadena filtrada, consideraría:
output.reserve(str.size() + output.size());
std::copy_if(str.cbegin(),
str.cend(),
std::back_inserter(output),
predicate});
En la pregunta original, el predicado es [](char c){return c != 'a';}
Según otras respuestas, aquí va un ejemplo más en el que eliminé todos los caracteres especiales en una cadena determinada:
#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;
}
Entrada vs Salida:
Input:ra,..pha
Output:rapha
Input:ovo,
Output:ovo
Input:a.vo
Output:avo
Input:oi?
Output:oi
Supongo que el método std: remove funciona pero estaba dando algún problema de compatibilidad con las inclusiones, así que terminé escribiendo esta pequeña función:
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);
}
Solo usa como
myString = removeCharsFromString (myString, "abc \ r");
y eliminará todas las ocurrencias de la lista de caracteres dada.
Esto también podría ser un poco más eficiente ya que el ciclo regresa después de la primera coincidencia, por lo que en realidad hacemos menos comparaciones.
Así es como lo hago:
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;
}
Básicamente, cada vez que encuentro un carácter determinado, avanzo el desplazamiento y reubico el carácter en el índice correcto. No sé si esto es correcto o eficiente, estoy comenzando (una vez más) en C ++ y agradecería cualquier comentario al respecto.
#include <string>
#include <algorithm>
std::string str = "YourString";
char chars[] = {'Y', 'S'};
str.erase (std::remove(str.begin(), str.end(), chars[i]), str.end());
Eliminará Y y S mayúsculas de str, dejando "ourtring".
Tenga en cuenta que remove
es un algoritmo y necesita el encabezado <algorithm>
incluido.
''
no es un personaje de hecho.