Я использую следующее:
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
исходной длине строки. Для каждого входного символа я провожу тест на O(1)
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());
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());
Если у вас есть 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';}
Этот код удаляет повторение символов, т. Е. Если ввод - 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;
Основываясь на других ответах, вот еще один пример, в котором я удалил все специальные символы в данной строке:
#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;
}
Обычно всякий раз, когда я нахожу данный char, я увеличиваю смещение и перемещаю char в правильный индекс. Я не знаю, правильно это или эффективно, я начинаю (снова) с 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 из str, оставив "ourtring".
Обратите внимание, что remove
это алгоритм, и он требует включения заголовка <algorithm>
.
''
действительно не персонаж.