Für diejenigen, die es nicht gut finden, alle Effizienz für die Codegröße zu opfern und "effizient" als eine Art von Eleganz zu sehen, sollte das Folgende einen guten Punkt treffen (und ich denke, die Template-Container-Klasse ist eine unglaublich elegante Ergänzung):
template < class ContainerT >
void tokenize(const std::string& str, ContainerT& tokens,
const std::string& delimiters = " ", bool trimEmpty = false)
{
std::string::size_type pos, lastPos = 0, length = str.length();
using value_type = typename ContainerT::value_type;
using size_type = typename ContainerT::size_type;
while(lastPos < length + 1)
{
pos = str.find_first_of(delimiters, lastPos);
if(pos == std::string::npos)
{
pos = length;
}
if(pos != lastPos || !trimEmpty)
tokens.push_back(value_type(str.data()+lastPos,
(size_type)pos-lastPos ));
lastPos = pos + 1;
}
}
Ich verwende normalerweise std::vector<std::string>
Typen als zweiten Parameter ( ContainerT
)... aber list<>
ist viel schneller als vector<>
für den Fall, dass ein direkter Zugriff nicht erforderlich ist, und Sie können sogar Ihre eigene String-Klasse erstellen und etwas verwenden wie std::list<subString>
wobei subString
macht keine Kopien für unglaubliche Geschwindigkeitssteigerungen.
Es ist mehr als doppelt so schnell wie das schnellste Tokenize auf dieser Seite und fast fünfmal so schnell wie einige andere. Mit den perfekten Parametertypen können Sie auch alle String- und Listenkopien eliminieren, was die Geschwindigkeit zusätzlich erhöht.
Außerdem erfolgt keine (äußerst ineffiziente) Rückgabe des Ergebnisses, sondern die Token werden als Verweis übergeben, so dass Sie auch Token über mehrere Aufrufe aufbauen können, wenn Sie dies wünschen.
Schließlich können Sie über einen letzten optionalen Parameter angeben, ob leere Token aus den Ergebnissen entfernt werden sollen.
Alles was es braucht ist std::string
... der Rest ist optional. Es verwendet keine Streams oder die Boost-Bibliothek, ist aber flexibel genug, um einige dieser fremden Typen natürlich zu akzeptieren.
686 Stimmen
Kumpel... Eleganz ist in meinen Augen nur eine schicke Umschreibung für "Effizienz, die hübsch aussieht". Scheuen Sie sich nicht, C-Funktionen und schnelle Methoden zu verwenden, um etwas zu erreichen, nur weil es nicht in einer Vorlage enthalten ist ;)
19 Stimmen
while (iss) { string subs; iss >> subs; cout << "Substring: " << sub << endl; }
0 Stimmen
@nlaq, Außer, dass Sie Ihr String-Objekt mit c_str() konvertieren müssten, und wieder zurück in einen String, wenn Sie es immer noch benötigen, um eine Zeichenfolge zu sein, nicht?
28 Stimmen
@Eduardo: das ist auch falsch... Sie müssen iss zwischen dem Versuch, einen anderen Wert zu streamen und der Verwendung dieses Wertes testen, d.h..
string sub; while (iss >> sub) cout << "Substring: " << sub << '\n';
1 Stimmen
Wie wäre es mit einem String-Tokenizer: cplusplus.com/referenz/string/strtok
14 Stimmen
Verschiedene Optionen in C++, um dies standardmäßig zu tun: cplusplus.com/faq/sequenzen/strings/split
27 Stimmen
Zur Eleganz gehört mehr als nur schöne Effizienz. Zu den eleganten Attributen gehören eine geringe Zeilenzahl und eine gute Lesbarkeit. IMHO ist Eleganz nicht gleichbedeutend mit Effizienz, sondern mit Wartungsfreundlichkeit.
3 Stimmen
Die meisten Antworten hier sind auffallend lateinzentriert. Viele der Antworten gehen davon aus, dass ein einzelnes Zeichen als "Leerzeichen" verwendet werden kann, obwohl die Frage das Begrenzungszeichen als Leerzeichen definiert. Unicode hat mindestens 25 Leerzeichen. Aber die Worttrennung ist nicht nur ein Problem des Leerraums. In der Silbenschrift, wie z. B. im Tibetischen, ist die Wortabgrenzung eher ein semantisches als ein syntaktisches Problem. Daher ist die Verwendung von Leerzeichen zur Extraktion von Wörtern für viele Sprachen kein geeigneter Ansatz.
0 Stimmen
Kleiner Zusatz zum oben Gesagten. Sie können eine Gebietsschema-Facette hinzufügen, die Interpunktion als Leerzeichen behandelt, so dass Sie nicht brauchen, um das separat zu behandeln. codereview.stackexchange.com/a/57467/507
1 Stimmen
Ihr ursprünglicher Code ist eleganter als die Antworten.