Все это хорошо документировано на справочных сайтах . Но если вы не знали об этих функциях, вы легко могли бы делать такие вещи вручную:
std::string output;
output.reserve(str.size());// optional, avoids buffer reallocations in the loopfor(size_t i =0; i < str.size();++i)if(str[i]!='a') output += str[i];
@jww: Я полагаю, вы говорите о последнем образце кода и nисходной длине строки. Для каждого входного символа я провожу тест на O(1)1 символ и добавляю 0 или 1 символ. Добавление символа O(1), O(current_length)если зарезервировано достаточно памяти или выделен новый буфер. Если вы сделаете это output.reserve(str.size())до цикла, этого никогда не произойдет, и у вас будут глобальные O(n)затраты. В противном случае, асимптотически, я предполагаю, что стоимость O(n . log(n) )связана со стратегией перераспределения контейнеров STL.
Антуан
5
Мне нужен #include <алгоритм>
S Meaden
Хороший ответ. Всегда хорошо, если в ответе много решений. Для меня forнаиболее подходит решение с .
Дмитрий Ничипоренко
@DmitryNichiporenko, ответ с for не может быть самым подходящим. Если у вас есть предикат или непустой вывод, я бы предпочел рассмотреть: output.reserve (str.size () + output.size ()); std :: copy_if (str.begin (), str.end (), std :: back_inserter (вывод), [] (char c) {предикат возврата (c);});
jimifiki
11
Алгоритм std::replaceработает для каждого элемента в заданной последовательности (поэтому он заменяет элементы другими элементами и не может заменить его ничем ). Но не бывает пустого персонажа. Если вы хотите удалить элементы из последовательности, следующие элементы должны быть перемещены , и std::replaceэто не работает.
Вы можете попробовать использовать std::remove( вместе сstd::erase ) для этого.
stringRemoveChar(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;}
Вот как я это сделал.
Или вы можете сделать, как сказал Антуан:
См. Этот вопрос,
который отвечает на ту же проблему. В твоем случае:
и он удалит все вхождения данного списка символов.
Это также может быть немного более эффективным, поскольку цикл возвращается после первого совпадения, поэтому на самом деле мы проводим меньше сравнений.
Вы угадали. Вместо того, чтобы писать свои собственные, лучше выяснить, почему нельзя использовать стандартные заголовки C ++.
xtofl
Что ж, это личное мнение, xtofl, не всегда хорошо использовать 3-й код, если вы на самом деле не знаете, что он делает, или производительности, вместо того, чтобы писать то, что вам конкретно нужно.
Дэмиен
1
Я понимаю, что ты имеешь в виду. Однако именно скромность заставляет меня выбирать версию, которая была проверена, протестирована и оптимизирована профессиональными разработчиками библиотеки, работающими полный рабочий день, а не моей собственной. Стандартной библиотеки можно считать необходимыми знаниями: его функции, а также его выполнения сложности.
xtofl
Помимо строк, это решение проблемы C ++ на языке C. Я не думаю, что это должно было быть отклонено.
Обычно всякий раз, когда я нахожу данный char, я увеличиваю смещение и перемещаю char в правильный индекс. Я не знаю, правильно это или эффективно, я начинаю (снова) с C ++, и я был бы признателен за любой вклад по этому поводу.
''
действительно не персонаж.Ответы:
По сути,
replace
заменяет символ другим и''
не является персонажем. То, что вы ищетеerase
.См. Этот вопрос, который отвечает на ту же проблему. В твоем случае:
Или используйте,
boost
если это вариант для вас, например:Все это хорошо документировано на справочных сайтах . Но если вы не знали об этих функциях, вы легко могли бы делать такие вещи вручную:
источник
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
) для этого.источник
Использование
copy_if
:источник
Вот как я это сделал.
Или вы можете сделать, как сказал Антуан:
источник
Если у вас есть
predicate
и / или непустой элементoutput
для заполнения отфильтрованной строкой, я бы подумал:В исходном вопросе предикат
[](char c){return c != 'a';}
источник
Этот код удаляет повторение символов, т. Е. Если ввод - aaabbcc, то вывод будет abc. (массив должен быть отсортирован, чтобы этот код работал)
источник
Основываясь на других ответах, вот еще один пример, в котором я удалил все специальные символы в данной строке:
Вход против выхода:
источник
Я предполагаю, что метод std: remove работает, но он вызывал некоторую проблему совместимости с включениями, поэтому я написал эту небольшую функцию:
Просто используйте как
и он удалит все вхождения данного списка символов.
Это также может быть немного более эффективным, поскольку цикл возвращается после первого совпадения, поэтому на самом деле мы проводим меньше сравнений.
источник
Вот как я это делаю:
Обычно всякий раз, когда я нахожу данный char, я увеличиваю смещение и перемещаю char в правильный индекс. Я не знаю, правильно это или эффективно, я начинаю (снова) с C ++, и я был бы признателен за любой вклад по этому поводу.
источник
Удалит заглавные буквы Y и S из str, оставив "ourtring".
Обратите внимание, что
remove
это алгоритм, и он требует включения заголовка<algorithm>
.источник