Jaki jest preferowany sposób usuwania spacji z łańcucha w C ++? Mógłbym zapętlić wszystkie postacie i zbudować nowy ciąg, ale czy jest lepszy sposób?
Jaki jest preferowany sposób usuwania spacji z łańcucha w C ++? Mógłbym zapętlić wszystkie postacie i zbudować nowy ciąg, ale czy jest lepszy sposób?
Odpowiedzi:
Najlepiej jest użyć algorytmu remove_if
i isspace:
remove_if(str.begin(), str.end(), isspace);
Teraz sam algorytm nie może zmienić kontenera (tylko modyfikować wartości), więc faktycznie przetasowuje wartości i zwraca wskaźnik do miejsca, w którym powinien być teraz koniec. Musimy więc wywołać string :: erase, aby faktycznie zmodyfikować długość kontenera:
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
Należy również pamiętać, że remove_if utworzy co najwyżej jedną kopię danych. Oto przykładowa implementacja:
template<typename T, typename P>
T remove_if(T beg, T end, P pred)
{
T dest = beg;
for (T itr = beg;itr != end; ++itr)
if (!pred(*itr))
*(dest++) = *itr;
return dest;
}
erase
później zadzwonić . To zwróci poprawny wynik.
isspace
jest UB dla wszystkich zestawów znaków oprócz oryginalnego 7-bitowego ASCII. C99 § 7.4 / 1. to nie dziwi mnie, że to było upvoted w wysokości 71 głosami teraz, mimo że bardzo złe rady.
isspace
, dla wszystkich znaków spoza ASCII, z domyślnym wyborem sygnatury w praktyce char
. W ten sposób ma niezdefiniowane zachowanie . Powtarzam to, ponieważ podejrzewam celową próbę zatopienia tego faktu w hałasie.
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' ');
str.erase(end_pos, str.end());
<algorithm>
aby to działało.
Od gamedev
string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end());
::isspace
to UB.
Czy możesz użyć Boost String Algo? http://www.boost.org/doc/libs/1_35_0/doc/html/string_algo/usage.html#id1290573
erase_all(str, " ");
remove_if(str.begin(), str.end(), isspace);
Matt Price. Nie wiem dlaczego. W rzeczywistości wszystkie elementy wspomagające, które mają alternatywy STL, są wolniejsze niż odpowiadające im gcc (wszystkie te, które testowałem). Niektóre z nich są znacznie wolniejsze! (do 5 razy we wstawkach unordered_map) Być może dzieje się tak z powodu pamięci podręcznej procesora w udostępnianym środowisku lub czegoś podobnego.
Do przycinania użyj algorytmów ciągu wzmocnionego :
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;
// ...
string str1(" hello world! ");
trim(str1); // str1 == "hello world!"
Możesz użyć tego rozwiązania do usunięcia znaku:
#include <algorithm>
#include <string>
using namespace std;
str.erase(remove(str.begin(), str.end(), char_to_remove), str.end());
Cześć, możesz zrobić coś takiego. Ta funkcja usuwa wszystkie spacje.
string delSpaces(string &str)
{
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
return str;
}
Zrobiłem inną funkcję, która usuwa wszystkie niepotrzebne spacje.
string delUnnecessary(string &str)
{
int size = str.length();
for(int j = 0; j<=size; j++)
{
for(int i = 0; i <=j; i++)
{
if(str[i] == ' ' && str[i+1] == ' ')
{
str.erase(str.begin() + i);
}
else if(str[0]== ' ')
{
str.erase(str.begin());
}
else if(str[i] == '\0' && str[i-1]== ' ')
{
str.erase(str.end() - 1);
}
}
}
return str;
}
string replaceinString(std::string str, std::string tofind, std::string toreplace)
{
size_t position = 0;
for ( position = str.find(tofind); position != std::string::npos; position = str.find(tofind,position) )
{
str.replace(position ,1, toreplace);
}
return(str);
}
Użyj tego:
string replace = replaceinString(thisstring, " ", "%20");
string replace2 = replaceinString(thisstring, " ", "-");
string replace3 = replaceinString(thisstring, " ", "+");
Jeśli chcesz to zrobić za pomocą łatwego makra, oto jedno:
#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end())
Zakłada się, że zrobiłeś #include <string>
oczywiście.
Nazwij to tak:
std::string sName = " Example Name ";
REMOVE_SPACES(sName);
printf("%s",sName.c_str()); // requires #include <stdio.h>
Długo korzystałem z poniższej metody - nie jestem pewien jej złożoności.
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());
kiedy chcesz usunąć postać, ' '
a niektóre na przykład -
użyć
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());
podobnie po prostu zwiększ ||
liczbę, jeśli liczba znaków, które chcesz usunąć, nie wynosi 1
ale jak wspominają inni, idiom usuwania usuń również wydaje się w porządku.
string removeSpaces(string word) {
string newWord;
for (int i = 0; i < word.length(); i++) {
if (word[i] != ' ') {
newWord += word[i];
}
}
return newWord;
}
Ten kod w zasadzie pobiera ciąg znaków i iteruje wszystkie zawarte w nim znaki. Następnie sprawdza, czy ten ciąg jest białą spacją, jeśli nie jest, to znak jest dodawany do nowego ciągu.
#include <algorithm> using namespace std; int main() { . . s.erase( remove( s.begin(), s.end(), ' ' ), s.end() ); . . }
Referencje zaczerpnięte z tego forum.
W C ++ 20 możesz używać darmowej funkcji std :: erase
std::string str = " Hello World !";
std::erase(str, ' ');
Pełny przykład:
#include<string>
#include<iostream>
int main() {
std::string str = " Hello World !";
std::erase(str, ' ');
std::cout << "|" << str <<"|";
}
Drukuję | tak, że jest oczywiste, że przestrzeń na początku jest również usuwana.
Uwaga: usuwa to tylko spację, a nie każdą inną możliwą postać, którą można uznać za spację, patrz https://en.cppreference.com/w/cpp/string/byte/isspace
Usuwa wszystkie znaki spacji, takie jak tabulatory i podziały wierszy (C ++ 11):
string str = " \n AB cd \t efg\v\n";
str = regex_replace(str,regex("\\s"),"");
string str = "2C F4 32 3C B9 DE";
str.erase(remove(str.begin(),str.end(),' '),str.end());
cout << str << endl;
wyjście: 2CF4323CB9DE
string removespace(string str)
{
int m = str.length();
int i=0;
while(i<m)
{
while(str[i] == 32)
str.erase(i,1);
i++;
}
}
length()
zwraca a size_t
, a nie an int
. erase()
bierze, a size_type
nie int
. Funkcja prawdopodobnie zawiedzie, jeśli napotkane zostaną dwie kolejne spacje, ponieważ indeks jest zawsze zwiększany. Jeśli jedna spacja zostanie usunięta, pętla będzie czytać poza granicami łańcucha. Prawdopodobnie powinieneś usunąć tę odpowiedź, ponieważ wymaga ona dużej pomocy.
Obawiam się, że to najlepsze rozwiązanie, jakie mogę wymyślić. Możesz jednak użyć funkcji replace (), aby wstępnie przydzielić wcześniej minimalną wymaganą pamięć, aby nieco przyspieszyć. Otrzymasz nowy ciąg znaków, który prawdopodobnie będzie krótszy, ale zajmuje tyle samo pamięci, ale unikniesz realokacji.
EDYCJA: W zależności od twojej sytuacji, może to powodować mniejsze obciążenie ogólne niż pomieszanie postaci.
Powinieneś wypróbować różne podejścia i przekonać się, co jest dla Ciebie najlepsze: możesz nie mieć żadnych problemów z wydajnością.