Cách ưa thích để loại bỏ khoảng trắng khỏi chuỗi trong C ++ là gì? Tôi có thể lặp qua tất cả các ký tự và xây dựng một chuỗi mới, nhưng có cách nào tốt hơn không?
Cách ưa thích để loại bỏ khoảng trắng khỏi chuỗi trong C ++ là gì? Tôi có thể lặp qua tất cả các ký tự và xây dựng một chuỗi mới, nhưng có cách nào tốt hơn không?
Câu trả lời:
Điều tốt nhất để làm là sử dụng thuật toán remove_if
và isspace:
remove_if(str.begin(), str.end(), isspace);
Bây giờ, thuật toán tự nó không thể thay đổi vùng chứa (chỉ sửa đổi các giá trị), vì vậy nó thực sự xáo trộn các giá trị xung quanh và trả về một con trỏ đến nơi kết thúc bây giờ. Vì vậy, chúng ta phải gọi chuỗi :: erase để thực sự sửa đổi độ dài của container:
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
Chúng ta cũng nên lưu ý rằng remove_if sẽ tạo tối đa một bản sao của dữ liệu. Đây là một triển khai mẫu:
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
sau đó. Điều đó sẽ trả về kết quả chính xác.
isspace
này là UB cho tất cả các bộ ký tự ngoại trừ ASCII 7 bit gốc. C99 §7.4 / 1. điều đó không làm tôi ngạc nhiên khi nó đã được nâng lên thành giai điệu với 71 phiếu bầu, mặc dù là Lời khuyên rất tệ.
isspace
, đối với tất cả các ký tự không phải ASCII, với lựa chọn mặc định trong thực tế là ký kết cho char
. Do đó, nó có hành vi không xác định . Tôi đang lặp lại nó bởi vì tôi nghi ngờ một nỗ lực cố ý để nhấn chìm sự thật đó trong tiếng ồn.
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' ');
str.erase(end_pos, str.end());
<algorithm>
để làm việc này.
Từ gamedev
string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end());
::isspace
là UB.
Bạn có thể sử dụng Boost String Algo? http://www.boost.org/doc/libs/1_35_0/doc/html/opes_algo/usage.html#id1290573
erase_all(str, " ");
remove_if(str.begin(), str.end(), isspace);
Matt Price đã đề cập. Tôi không biết tại sao. Trên thực tế, tất cả các công cụ tăng cường, có các lựa chọn thay thế STL, đều chậm hơn các công cụ gcc tương ứng (Tất cả những công cụ tôi đã thử nghiệm). Một số trong số họ là rất chậm! (tối đa 5 lần khi chèn unordered_map) Có thể đó là do bộ đệm CPU của môi trường dùng chung hoặc một cái gì đó tương tự.
Để cắt tỉa, sử dụng thuật toán chuỗi boost :
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;
// ...
string str1(" hello world! ");
trim(str1); // str1 == "hello world!"
Bạn có thể sử dụng giải pháp này để xóa char:
#include <algorithm>
#include <string>
using namespace std;
str.erase(remove(str.begin(), str.end(), char_to_remove), str.end());
Xin chào, bạn có thể làm một cái gì đó như thế. Hàm này xóa tất cả các khoảng trắng.
string delSpaces(string &str)
{
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
return str;
}
Tôi đã thực hiện một chức năng khác, đó là xóa tất cả các không gian không cần thiết.
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);
}
sử dụng nó:
string replace = replaceinString(thisstring, " ", "%20");
string replace2 = replaceinString(thisstring, " ", "-");
string replace3 = replaceinString(thisstring, " ", "+");
Nếu bạn muốn làm điều này với một macro dễ dàng, đây là một:
#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end())
Điều này giả định bạn đã làm #include <string>
tất nhiên.
Gọi nó như vậy:
std::string sName = " Example Name ";
REMOVE_SPACES(sName);
printf("%s",sName.c_str()); // requires #include <stdio.h>
Tôi đã sử dụng các công việc dưới đây xung quanh lâu - không chắc về sự phức tạp của nó.
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());
khi bạn muốn loại bỏ ký tự ' '
và một số ví dụ -
sử dụng
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());
tương tự, chỉ cần tăng ||
số lượng ký tự bạn muốn xóa không phải là 1
nhưng như đã đề cập bởi những người khác, xóa thành ngữ cũng có vẻ tốt.
string removeSpaces(string word) {
string newWord;
for (int i = 0; i < word.length(); i++) {
if (word[i] != ' ') {
newWord += word[i];
}
}
return newWord;
}
Mã này về cơ bản lấy một chuỗi và lặp qua mọi ký tự trong nó. Sau đó, nó kiểm tra xem chuỗi đó có phải là khoảng trắng hay không, nếu không thì ký tự đó sẽ được thêm vào chuỗi mới.
#include <algorithm> using namespace std; int main() { . . s.erase( remove( s.begin(), s.end(), ' ' ), s.end() ); . . }
Tham khảo lấy từ diễn đàn này .
Trong C ++ 20, bạn có thể sử dụng chức năng miễn phí std :: erase
std::string str = " Hello World !";
std::erase(str, ' ');
Ví dụ đầy đủ:
#include<string>
#include<iostream>
int main() {
std::string str = " Hello World !";
std::erase(str, ' ');
std::cout << "|" << str <<"|";
}
Tôi in | do đó, rõ ràng là không gian lúc bắt đầu cũng bị loại bỏ.
lưu ý: điều này chỉ xóa khoảng trắng, không phải mọi ký tự có thể khác có thể được coi là khoảng trắng, xem https://en.cppreference.com/w/cpp/opes/byte/isspace
Xóa tất cả các ký tự khoảng trắng như tab và ngắt dòng (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;
đầu ra: 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()
trả về a size_t
, không phải an int
. erase()
mất một size_type
, không phải một int
. Hàm có thể sẽ thất bại nếu gặp hai khoảng trắng liên tiếp do chỉ số luôn tăng. Nếu một khoảng trắng bị xóa, thì vòng lặp sẽ đọc vượt ra ngoài giới hạn của chuỗi. Bạn có lẽ nên xóa câu trả lời này vì nó cần rất nhiều sự giúp đỡ.
Tôi sợ đó là giải pháp tốt nhất mà tôi có thể nghĩ ra. Nhưng bạn có thể sử dụng dự trữ () để phân bổ trước bộ nhớ tối thiểu cần thiết trước để tăng tốc mọi thứ một chút. Bạn sẽ kết thúc với một chuỗi mới có thể sẽ ngắn hơn nhưng chiếm cùng một lượng bộ nhớ, nhưng bạn sẽ tránh được việc phân bổ lại.
EDIT: Tùy thuộc vào tình huống của bạn, điều này có thể phát sinh ít chi phí hơn so với các nhân vật lộn xộn xung quanh.
Bạn nên thử các cách tiếp cận khác nhau và xem điều gì là tốt nhất cho bạn: bạn có thể không có bất kỳ vấn đề nào về hiệu suất.