Tôi đang sử dụng sau:
replace (str1.begin(), str1.end(), 'a' , '')
Nhưng điều này gây ra lỗi biên dịch.
Tôi đang sử dụng sau:
replace (str1.begin(), str1.end(), 'a' , '')
Nhưng điều này gây ra lỗi biên dịch.
Câu trả lời:
Về cơ bản, replace
thay thế một ký tự bằng một ký tự khác và ''
không phải là một ký tự. Những gì bạn đang tìm kiếm là erase
.
Xem câu hỏi này trả lời cùng một vấn đề. Trong trường hợp của bạn:
#include <algorithm>
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
Hoặc sử dụng boost
nếu đó là một tùy chọn cho bạn, như:
#include <boost/algorithm/string.hpp>
boost::erase_all(str, "a");
Tất cả những điều này đều được ghi chép đầy đủ trên các trang web tham khảo . Nhưng nếu bạn không biết những chức năng này, bạn có thể dễ dàng làm những việc này bằng tay:
std::string output;
output.reserve(str.size()); // optional, avoids buffer reallocations in the loop
for(size_t i = 0; i < str.size(); ++i)
if(str[i] != 'a') output += str[i];
O(n^2)
?
n
là độ dài chuỗi ban đầu. Đối với mỗi ký tự đầu vào, tôi thực hiện kiểm tra 1 ký tự O(1)
và thêm 0 hoặc 1 ký tự. Ký tự nối thêm là O(1)
đủ bộ nhớ được dự trữ hoặc O(current_length)
nếu một bộ đệm mới được cấp phát. Nếu bạn làm output.reserve(str.size())
trước vòng lặp, điều này không bao giờ xảy ra và bạn phải O(n)
trả chi phí toàn cầu . Nếu không, tôi đoán chi phí là O(n . log(n) )
do chiến lược phân bổ lại vùng chứa STL.
for
là phù hợp nhất.
Thuật toán std::replace
hoạt động trên mỗi phần tử trên một chuỗi nhất định (vì vậy nó thay thế các phần tử bằng các phần tử khác nhau và không thể thay thế nó bằng không ). Nhưng không có ký tự trống . Nếu bạn muốn xóa các phần tử khỏi một chuỗi, các phần tử sau phải được di chuyển và std::replace
không hoạt động như vậy.
Bạn có thể cố gắng sử dụng std::remove
( cùng vớistd::erase
) để đạt được điều này.
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
string RemoveChar(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;
}
Đây là cách tôi đã làm điều đó.
Hoặc bạn có thể làm như Antoine đã đề cập:
Xem câu hỏi này trả lời cùng một vấn đề. Trong trường hợp của bạn:
#include <algorithm> str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
Mã này loại bỏ sự lặp lại của các charecters, tức là nếu đầu vào là aaabbcc thì đầu ra sẽ là abc.
cin >> s;
ans = "";
ans += s[0];
for(int i = 1;i < s.length();++i)
if(s[i] != s[i-1])
ans += s[i];
cout << ans << endl;
Trong trường hợp bạn có predicate
và / hoặc không để trống output
để điền vào chuỗi đã lọc, tôi sẽ xem xét:
output.reserve(str.size() + output.size());
std::copy_if(str.cbegin(),
str.cend(),
std::back_inserter(output),
predicate});
Trong câu hỏi ban đầu, vị ngữ là [](char c){return c != 'a';}
Dựa trên các câu trả lời khác, đây là một ví dụ khác mà tôi đã xóa tất cả các ký tự đặc biệt trong một chuỗi nhất định:
#include <iostream>
#include <string>
#include <algorithm>
std::string chars(".,?!.:;_,!'\"-");
int main(int argc, char const *argv){
std::string input("oi?");
std::string output = eraseSpecialChars(input);
return 0;
}
std::string eraseSpecialChars(std::string str){
std::string newStr;
newStr.assign(str);
for(int i = 0; i < str.length(); i++){
for(int j = 0; j < chars.length(); j++ ){
if(str.at(i) == chars.at(j)){
char c = str.at(i);
newStr.erase(std::remove(newStr.begin(), newStr.end(), c), newStr.end());
}
}
}
return newStr;
}
Đầu vào so với Đầu ra:
Input:ra,..pha
Output:rapha
Input:ovo,
Output:ovo
Input:a.vo
Output:avo
Input:oi?
Output:oi
Tôi đoán phương pháp std: remove hoạt động nhưng nó gây ra một số vấn đề tương thích với bao gồm vì vậy tôi đã kết thúc bằng cách viết hàm nhỏ này:
string removeCharsFromString(const string str, char* charsToRemove )
{
char c[str.length()+1]; // + terminating char
const char *p = str.c_str();
unsigned int z=0, size = str.length();
unsigned int x;
bool rem=false;
for(x=0; x<size; x++)
{
rem = false;
for (unsigned int i = 0; charsToRemove[i] != 0; i++)
{
if (charsToRemove[i] == p[x])
{
rem = true;
break;
}
}
if (rem == false) c[z++] = p[x];
}
c[z] = '\0';
return string(c);
}
Chỉ cần sử dụng như
myString = removeCharsFromString (myString, "abc \ r");
và nó sẽ loại bỏ tất cả sự xuất hiện của danh sách char đã cho.
Điều này cũng có thể hiệu quả hơn một chút vì vòng lặp trở lại sau trận đấu đầu tiên, vì vậy chúng tôi thực sự thực hiện ít so sánh hơn.
Đây là cách tôi làm điều đó:
std::string removeAll(std::string str, char c) {
size_t offset = 0;
size_t size = str.size();
size_t i = 0;
while (i < size - offset) {
if (str[i + offset] == c) {
offset++;
}
if (offset != 0) {
str[i] = str[i + offset];
}
i++;
}
str.resize(size - offset);
return str;
}
Về cơ bản, bất cứ khi nào tôi tìm thấy một char nhất định, tôi sẽ tăng phần bù và chuyển vị trí của char đến đúng chỉ mục. Tôi không biết liệu điều này có chính xác hay hiệu quả hay không, tôi đang bắt đầu (một lần nữa) ở C ++ và tôi đánh giá cao bất kỳ đầu vào nào về điều đó.
#include <string>
#include <algorithm>
std::string str = "YourString";
char chars[] = {'Y', 'S'};
str.erase (std::remove(str.begin(), str.end(), chars[i]), str.end());
Sẽ xóa Y và S viết hoa khỏi str, để lại "ourtring".
Lưu ý rằng đó remove
là một thuật toán và cần có tiêu đề <algorithm>
.
''
thực sự không phải là một nhân vật.