Я використовую наступне:
replace (str1.begin(), str1.end(), 'a' , '')
Але це дає помилку компіляції.
Я використовую наступне:
replace (str1.begin(), str1.end(), 'a' , '')
Але це дає помилку компіляції.
Відповіді:
В основному, replace
замінює персонажа іншим і ''
не є персонажем. Те, що ви шукаєте erase
.
Дивіться це запитання, яке відповідає на ту саму проблему. У вашому випадку:
#include <algorithm>
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
Або скористайтеся, boost
якщо це варіант для вас, наприклад:
#include <boost/algorithm/string.hpp>
boost::erase_all(str, "a");
Все це добре задокументовано на довідкових веб-сайтах . Але якщо ви не знали про ці функції, ви могли б легко робити такі речі вручну:
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
це оригінальна довжина рядка. Для кожного введеного символу я роблю 1 тест на O(1)
символи та додаю 0 або 1 символ. Додавання символу - O(1)
це достатня кількість пам’яті, зарезервована, або O(current_length)
якщо виділено новий буфер. Якщо ви робите це output.reserve(str.size())
до циклу, цього ніколи не трапляється, і у вас є загальна O(n)
вартість. В іншому випадку асимптотично, я думаю, ціна O(n . log(n) )
пов’язана із стратегією перерозподілу контейнерів STL.
for
найбільш підходящим є рішення із .
Алгоритм std::replace
працює для кожного елемента в заданій послідовності (тому він замінює елементи різними елементами і не може замінити його нічим ). Але порожнього персонажа немає . Якщо ви хочете видалити елементи з послідовності, наступні елементи потрібно перемістити , і std::replace
це не працює так.
Ви можете спробувати використовувати std::remove
( разом зstd::erase
) для досягнення цього.
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
Використання copy_if
:
#include <string>
#include <iostream>
#include <algorithm>
int main() {
std::string s1 = "a1a2b3c4a5";
char s2[256];
std::copy_if(s1.begin(), s1.end(), s2, [](char c){return c!='a';});
std::cout << s2 << std::endl;
return 0;
}
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;
}
Ось як я це зробив.
Або ви можете зробити те, що згадав Антуан:
Дивіться це запитання, яке відповідає на ту саму проблему. У вашому випадку:
#include <algorithm> str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
Цей код усуває повторення символів, тобто, якщо вхідний сигнал aaabbcc, тоді вихід буде 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;
Якщо у вас є predicate
та / або не пусте місце output
для заповнення відфільтрованим рядком, я б розглянув:
output.reserve(str.size() + output.size());
std::copy_if(str.cbegin(),
str.cend(),
std::back_inserter(output),
predicate});
У вихідному питанні присудок є [](char c){return c != 'a';}
Виходячи з інших відповідей, ось ще один приклад, коли я видалив усі спеціальні символи в даному рядку:
#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;
}
Вхід проти виходу:
Input:ra,..pha
Output:rapha
Input:ovo,
Output:ovo
Input:a.vo
Output:avo
Input:oi?
Output:oi
Я здогадуюсь, що метод std: remove працює, але це дало певну проблему сумісності з включеннями, тому я закінчив писати цю маленьку функцію:
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);
}
Просто використовуйте як
myString = removeCharsFromString (myString, "abc \ r");
і це видалить усі випадки подання цього списку символів.
Це також може бути трохи ефективнішим, оскільки цикл повертається після першого збігу, тому насправді ми робимо менше порівняння.
Ось як я це роблю:
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;
}
В основному, коли я знаходжу певний символ, я переміщую зміщення і переміщую його до правильного індексу. Я не знаю, чи це правильно чи ефективно, я починаю (ще раз) на C ++, і я був би вдячний за будь-який вступ щодо цього.
#include <string>
#include <algorithm>
std::string str = "YourString";
char chars[] = {'Y', 'S'};
str.erase (std::remove(str.begin(), str.end(), chars[i]), str.end());
Видалить великі букви Y та S з вулиці, залишивши "ourtring".
Зверніть увагу, що remove
це алгоритм і потребує <algorithm>
включення заголовка .
''
насправді не є персонажем.