Apa cara yang disukai untuk menghapus spasi dari string di C ++? Saya bisa mengulang semua karakter dan membuat string baru, tetapi apakah ada cara yang lebih baik?
Apa cara yang disukai untuk menghapus spasi dari string di C ++? Saya bisa mengulang semua karakter dan membuat string baru, tetapi apakah ada cara yang lebih baik?
Jawaban:
Hal terbaik untuk dilakukan adalah menggunakan algoritme remove_if
dan ruang:
remove_if(str.begin(), str.end(), isspace);
Sekarang algoritma itu sendiri tidak dapat mengubah wadah (hanya memodifikasi nilai-nilai), jadi itu benar-benar mengocok nilai-nilai di sekitar dan mengembalikan pointer ke tempat akhir sekarang seharusnya. Jadi kita harus memanggil string :: erase untuk benar-benar memodifikasi panjang wadah:
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
Kami juga harus mencatat bahwa remove_if akan membuat paling banyak satu salinan data. Berikut ini contoh implementasi:
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
sesudahnya. Itu akan mengembalikan hasil yang benar.
isspace
adalah UB untuk semua set karakter kecuali ASCII 7-bit asli. C99 §7.4 / 1. itu tidak mengejutkan saya bahwa itu sudah upvoted untuk lagu 71 orang sekarang, meskipun menjadi sangat buruk Saran.
isspace
, untuk semua karakter non-ASCII, dengan pilihan standar praktik dalam penandatanganan untuk char
. Dengan demikian ia memiliki perilaku yang tidak jelas . Saya mengulanginya karena saya curiga ada upaya yang disengaja untuk menenggelamkan fakta itu dalam kebisingan.
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' ');
str.erase(end_pos, str.end());
<algorithm>
ini agar berfungsi.
Dari gamedev
string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end());
::isspace
adalah UB.
Bisakah Anda menggunakan 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);
yang disebutkan oleh Matt Price. Saya tidak tahu kenapa. Sebenarnya, semua hal yang meningkatkan, yang memiliki alternatif STL, lebih lambat daripada yang gcc yang sesuai (Semua yang saya diuji). Beberapa dari mereka jauh lebih lambat! (hingga 5 kali dalam sisipan unordered_map) Mungkin itu karena cache CPU dari lingkungan bersama atau sesuatu seperti itu.
Untuk pemangkasan, gunakan algoritma peningkatan string :
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;
// ...
string str1(" hello world! ");
trim(str1); // str1 == "hello world!"
Anda dapat menggunakan solusi ini untuk menghapus char:
#include <algorithm>
#include <string>
using namespace std;
str.erase(remove(str.begin(), str.end(), char_to_remove), str.end());
Hai, Anda bisa melakukan hal seperti itu. Fungsi ini menghapus semua spasi.
string delSpaces(string &str)
{
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
return str;
}
Saya membuat fungsi lain, yang menghapus semua ruang yang tidak perlu.
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);
}
Gunakan:
string replace = replaceinString(thisstring, " ", "%20");
string replace2 = replaceinString(thisstring, " ", "-");
string replace3 = replaceinString(thisstring, " ", "+");
Jika Anda ingin melakukan ini dengan makro yang mudah, berikut ini:
#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end())
Ini mengasumsikan Anda sudah melakukan #include <string>
tentu saja.
Sebut seperti ini:
std::string sName = " Example Name ";
REMOVE_SPACES(sName);
printf("%s",sName.c_str()); // requires #include <stdio.h>
Saya menggunakan pekerjaan di bawah ini untuk waktu yang lama - tidak yakin tentang kerumitannya.
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());
ketika Anda ingin menghapus karakter ' '
dan beberapa misalnya -
digunakan
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());
juga hanya menambah ||
jika jumlah karakter yang ingin Anda hapus bukan 1
tetapi seperti yang disebutkan oleh orang lain menghapus idiom hapus juga tampak baik-baik saja.
string removeSpaces(string word) {
string newWord;
for (int i = 0; i < word.length(); i++) {
if (word[i] != ' ') {
newWord += word[i];
}
}
return newWord;
}
Kode ini pada dasarnya mengambil string dan beralih melalui setiap karakter di dalamnya. Itu kemudian memeriksa apakah string itu adalah spasi, jika tidak maka karakter ditambahkan ke string baru.
#include <algorithm> using namespace std; int main() { . . s.erase( remove( s.begin(), s.end(), ' ' ), s.end() ); . . }
Referensi diambil dari forum ini .
Di C ++ 20 Anda dapat menggunakan fungsi std :: erase gratis
std::string str = " Hello World !";
std::erase(str, ' ');
Contoh lengkap:
#include<string>
#include<iostream>
int main() {
std::string str = " Hello World !";
std::erase(str, ' ');
std::cout << "|" << str <<"|";
}
Saya mencetak | sehingga jelas bahwa ruang di awal juga dihilangkan.
catatan: ini hanya menghapus ruang, tidak setiap karakter lain yang mungkin dianggap sebagai spasi putih, lihat https://en.cppreference.com/w/cpp/string/byte/isspace
Menghapus semua karakter spasi putih seperti tab dan jeda baris (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;
output: 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()
mengembalikan a size_t
, bukan sebuah int
. erase()
mengambil size_type
, bukan int
. Fungsi ini mungkin akan gagal jika dua spasi berturut-turut ditemukan karena indeks selalu bertambah. Jika satu spasi dihilangkan, maka loop akan membaca di luar batas string. Anda mungkin harus menghapus jawaban ini karena butuh banyak bantuan.
Saya khawatir itu solusi terbaik yang bisa saya pikirkan. Tetapi Anda dapat menggunakan cadangan () untuk pra-alokasikan memori minimum yang diperlukan di muka untuk mempercepat segalanya. Anda akan berakhir dengan string baru yang mungkin akan lebih pendek tetapi membutuhkan jumlah memori yang sama, tetapi Anda akan menghindari realokasi.
EDIT: Tergantung pada situasi Anda, ini mungkin menimbulkan lebih sedikit overhead daripada karakter jumbling di sekitar.
Anda harus mencoba berbagai pendekatan dan melihat yang terbaik untuk Anda: Anda mungkin tidak memiliki masalah kinerja sama sekali.