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 loopfor(size_t i =0; i < str.size();++i)if(str[i]!='a') output += str[i];
Ist der von Ihnen bereitgestellte Algorithmus nicht O(n^2)?
JWW
@jww: Ich gehe davon aus, dass Sie über das letzte Codebeispiel sprechen und ndie 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.
Antoine
5
Ich brauchte #include <algorithm>
S Meaden
Gute Antwort. Es ist immer gut, wenn die Antwort viele Lösungen enthält. Für mich ist die Lösung mit dem foram besten geeignet.
Dmitry Nichiporenko
@DmitryNichiporenko die Antwort mit dem für kann nicht die am besten geeignete sein. Wenn Sie ein Prädikat oder eine nicht leere Ausgabe haben, würde ich eher Folgendes in Betracht ziehen: output.reserve (str.size () + output.size ()); std :: copy_if (str.begin (), str.end (), std :: back_inserter (Ausgabe), [] (char c) {Rückgabeprädikat (c);});
Jimifiki
10
Der Algorithmus std::replacearbeitet 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::replacefunktionieren nicht so.
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;}
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:
Falls Sie eine predicateund / oder eine nicht leere haben output, die mit der gefilterten Zeichenfolge gefüllt werden soll, würde ich Folgendes in Betracht ziehen:
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:
Sie raten richtig. Finden Sie besser heraus, warum Sie keine Standard-C ++ - Header verwenden können, anstatt Ihre eigenen zu schreiben.
xtofl
Nun, das ist eine persönliche Meinung.
Damien
1
Ich verstehe was du meinst. Es ist jedoch Demut, die mich dazu bringt, mich für die Version zu entscheiden, die von professionellen Vollzeitbibliotheksautoren überprüft, getestet und optimiert wurde, und nicht für meine eigene. Die Standardbibliothek kann als erforderliches Wissen angesehen werden: ihre Funktionen sowie ihre Laufzeitkomplexität.
xtofl
Abgesehen von den Zeichenfolgen ist es eine C-Lösung für ein C ++ - Problem. Ich denke nicht, dass dies hätte abgelehnt werden sollen.
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.
''
ist in der Tat kein Charakter.Antworten:
Ersetzt grundsätzlich
replace
einen Charakter durch einen anderen und''
ist kein Charakter. Was Sie suchen, isterase
.Siehe diese Frage, die das gleiche Problem beantwortet. In deinem Fall:
Oder verwenden Sie,
boost
wenn dies eine Option für Sie ist, wie:Auf All dies ist gut dokumentierte Referenz Websites . Aber wenn Sie diese Funktionen nicht kennen, können Sie diese Dinge leicht von Hand erledigen:
quelle
O(n^2)
?n
die ursprüngliche Zeichenfolgenlänge ist. Für jedes Eingabezeichen mache ich 1 ZeichentestO(1)
und füge 0 oder 1 Zeichen hinzu. Das Anhängen von ZeichenO(1)
ist ausreichend Speicherplatz reserviert oderO(current_length)
wenn ein neuer Puffer zugewiesen wird. Wenn Sie diesoutput.reserve(str.size())
vor der Schleife tun, geschieht dies nie und Sie haben globaleO(n)
Kosten. Ansonsten asymptotisch sind die KostenO(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 undstd::replace
funktionieren nicht so.Sie können versuchen,
std::remove
( zusammen mitstd::erase
) dies zu erreichen.quelle
Verwenden von
copy_if
:quelle
So habe ich es gemacht.
Oder Sie könnten tun, was Antoine erwähnt hat:
quelle
Dieser Code entfernt die Wiederholung von Zeichen, dh wenn die Eingabe aaabbcc ist, ist die Ausgabe abc.
quelle
Falls Sie eine
predicate
und / oder eine nicht leere habenoutput
, die mit der gefilterten Zeichenfolge gefüllt werden soll, würde ich Folgendes in Betracht ziehen:In der ursprünglichen Frage lautet das Prädikat
[](char c){return c != 'a';}
quelle
Basierend auf anderen Antworten folgt ein weiteres Beispiel, in dem ich alle Sonderzeichen in einer bestimmten Zeichenfolge entfernt habe:
Input vs Output:
quelle
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:
Verwenden Sie einfach als
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.
quelle
So mache ich es:
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.
quelle
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.quelle