Ich benutze folgendes:
replace (str1.begin(), str1.end(), 'a' , '')
Dies führt jedoch zu einem Kompilierungsfehler.
Ich benutze folgendes:
replace (str1.begin(), str1.end(), 'a' , '')
Dies führt jedoch zu einem Kompilierungsfehler.
Antworten:
Ersetzt grundsätzlich replace
einen Charakter durch einen anderen und ''
ist kein Charakter. Was Sie suchen, ist erase
.
Siehe diese Frage, die das gleiche Problem beantwortet. In deinem Fall:
#include <algorithm>
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
Oder verwenden Sie, boost
wenn dies eine Option für Sie ist, wie:
#include <boost/algorithm/string.hpp>
boost::erase_all(str, "a");
Auf All dies ist gut dokumentierte Referenz Websites . Aber wenn Sie diese Funktionen nicht kennen, können Sie diese Dinge leicht von Hand erledigen:
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
die ursprüngliche Zeichenfolgenlänge ist. Für jedes Eingabezeichen mache ich 1 Zeichentest O(1)
und füge 0 oder 1 Zeichen hinzu. Das Anhängen von Zeichen O(1)
ist ausreichend Speicherplatz reserviert oder O(current_length)
wenn ein neuer Puffer zugewiesen wird. Wenn Sie dies output.reserve(str.size())
vor der Schleife tun, geschieht dies nie und Sie haben globale O(n)
Kosten. Ansonsten asymptotisch sind die Kosten O(n . log(n) )
vermutlich auf die Strategie zur Neuzuweisung von STL-Containern zurückzuführen.
for
am besten geeignet.
Der Algorithmus std::replace
arbeitet pro Element in einer bestimmten Sequenz (ersetzt also Elemente durch andere Elemente und kann sie nicht durch nichts ersetzen ). Aber es gibt kein leeres Zeichen. Wenn Sie Elemente aus einer Sequenz entfernen möchten, müssen die folgenden Elemente verschoben werden und std::replace
funktionieren nicht so.
Sie können versuchen, std::remove
( zusammen mitstd::erase
) dies zu erreichen.
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;
}
So habe ich es gemacht.
Oder Sie könnten tun, was Antoine erwähnt hat:
Siehe diese Frage, die das gleiche Problem beantwortet. In deinem Fall:
#include <algorithm> str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
Dieser Code entfernt die Wiederholung von Zeichen, dh wenn die Eingabe aaabbcc ist, ist die Ausgabe 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;
Falls Sie eine predicate
und / oder eine nicht leere haben output
, die mit der gefilterten Zeichenfolge gefüllt werden soll, würde ich Folgendes in Betracht ziehen:
output.reserve(str.size() + output.size());
std::copy_if(str.cbegin(),
str.cend(),
std::back_inserter(output),
predicate});
In der ursprünglichen Frage lautet das Prädikat [](char c){return c != 'a';}
Basierend auf anderen Antworten folgt ein weiteres Beispiel, in dem ich alle Sonderzeichen in einer bestimmten Zeichenfolge entfernt habe:
#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;
}
Input vs Output:
Input:ra,..pha
Output:rapha
Input:ovo,
Output:ovo
Input:a.vo
Output:avo
Input:oi?
Output:oi
Ich denke, die Methode std: remove funktioniert, aber es gab ein Kompatibilitätsproblem mit den Includes, so dass ich am Ende diese kleine Funktion schrieb:
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);
}
Verwenden Sie einfach als
myString = removeCharsFromString (myString, "abc \ r");
und es wird das gesamte Auftreten der angegebenen Zeichenliste entfernt.
Dies könnte auch etwas effizienter sein, da die Schleife nach dem ersten Match zurückkehrt, sodass wir tatsächlich weniger Vergleiche durchführen.
So mache ich es:
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;
}
Grundsätzlich stelle ich den Offset immer dann vor, wenn ich ein bestimmtes Zeichen finde, und verschiebe das Zeichen in den richtigen Index. Ich weiß nicht, ob dies richtig oder effizient ist. Ich beginne (noch einmal) mit C ++ und würde mich über jede Eingabe dazu freuen.
#include <string>
#include <algorithm>
std::string str = "YourString";
char chars[] = {'Y', 'S'};
str.erase (std::remove(str.begin(), str.end(), chars[i]), str.end());
Entfernt das Kapital Y und S aus str und hinterlässt "ourtring".
Beachten Sie, dass dies remove
ein Algorithmus ist und der Header <algorithm>
enthalten sein muss.
''
ist in der Tat kein Charakter.