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 loopfor(size_t i =0; i < str.size();++i)if(str[i]!='a') output += str[i];
@jww: Supongo que estás hablando de la última muestra de código y nes 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.
Antoine
5
Necesitaba #incluir <algoritmo>
S Meaden
Buena respuesta. Siempre es bueno si la respuesta contiene muchas soluciones. Para mí, la solución con el fores la más adecuada.
Dmitry Nichiporenko
@DmitryNichiporenko la respuesta con for no puede ser la más adecuada. Si tiene un predicado o una salida no vacía, preferiría considerar: output.reserve (str.size () + output.size ()); std :: copy_if (str.begin (), str.end (), std :: back_inserter (salida), [] (char c) {predicado de retorno (c);});
jimifiki
10
El algoritmo std::replacefunciona 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::replaceno funciona así.
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;}
Así es como lo hice.
O podrías hacer lo que Antoine mencionó:
Vea esta pregunta
que responde al mismo problema. En tu caso:
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:
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.
Acertaste. En lugar de escribir el tuyo propio, es mejor que averigües por qué no puedes usar encabezados estándar de C ++.
xtofl
Bueno, esa es una opinión personal xtofl, no siempre es bueno usar el tercer código, en realidad no sabes lo que hace ni el rendimiento en lugar de escribir lo que necesitas específicamente.
Damien
1
Entiendo lo que dices. Sin embargo, es la humildad lo que me hace elegir la versión que ha sido revisada, probada y optimizada por escritores de bibliotecas profesionales a tiempo completo, en lugar de la mía. La biblioteca estándar puede considerarse un conocimiento necesario: sus funciones y su complejidad en tiempo de ejecución.
xtofl
Dejando a un lado las cadenas, es una solución de C a un problema de C ++. No creo que esto debería haber sido rechazado.
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.
''
no es un personaje de hecho.Respuestas:
Básicamente,
replace
reemplaza un personaje por otro y''
no es un personaje. Lo que estás buscando eserase
.Vea esta pregunta que responde al mismo problema. En tu caso:
O use
boost
si esa es una opción para usted, como: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:
fuente
O(n^2)
?n
es la longitud de la cadena original. Para cada carácter de entrada, hago una prueba deO(1)
1 carácter y agrego 0 o 1 carácter. La adición de caracteres es siO(1)
hay suficiente memoria reservada oO(current_length)
si se asigna un nuevo búfer. Si lo haceoutput.reserve(str.size())
antes del ciclo, esto nunca sucede y tiene unO(n)
costo global . De lo contrario, de forma asintótica, supongo que el costo seO(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 ystd::replace
no funciona así.Puede intentar usar
std::remove
( junto constd::erase
) para lograr esto.fuente
Usando
copy_if
:fuente
Así es como lo hice.
O podrías hacer lo que Antoine mencionó:
fuente
Este código elimina la repetición de caracteres, es decir, si la entrada es aaabbcc, la salida será abc.
fuente
En caso de que tenga un
predicate
y / o un no vacíooutput
para llenar con la cadena filtrada, consideraría:En la pregunta original, el predicado es
[](char c){return c != 'a';}
fuente
Según otras respuestas, aquí va un ejemplo más en el que eliminé todos los caracteres especiales en una cadena determinada:
Entrada vs Salida:
fuente
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:
Solo usa como
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.
fuente
Así es como lo hago:
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.
fuente
Eliminará Y y S mayúsculas de str, dejando "ourtring".
Tenga en cuenta que
remove
es un algoritmo y necesita el encabezado<algorithm>
incluido.fuente