C++. Сборник рецептов - [100]
>lstStr.erase(std::remove(lstStr.begin(), lstStr.end(), "cloudy"),
> lstStr.end());
Обратите внимание, что я использую >erase
, но на этот раз по какой-то причине мне требуется удалить из >list
все вхождения слова «cloudy», >remove
возвращает >iterator
, который передается в >erase
как начало удаляемого диапазона, a >end
передается в >erase
как конечная точка диапазона. В результате удаляются все объекты >obj
(вызывая их метод >delete
) из диапазона, для которого >obj == "cloudy"
равно истине. Но поведение этой строки может оказаться не совсем таким, как ожидается. Здесь мне требуется пояснить некоторую терминологию.
>remove
на самом деле ничего не удаляет. Он перемещает все, что не равно указанному значению, в начало последовательности и возвращает >iterator
, который ссылается на первый элемент, следующий за этими перемещенными элементами. Затем вы должны вызвать >erase
для контейнера, чтобы удалить объекты между [>p, end)
, где >p
— это >iterator
, возвращенный >remove
.
>remove
также имеет несколько вариантов. Что, если требуется удалить элементы, которые удовлетворяют некоторому предикату, а не просто равны какому-то значению? Используйте >remove_if
. Например, представьте, что есть класс с именем >Conn
, который представляет какой-то тип соединений. Если это соединение простаивает больше определенного значения, его требуется удалить. Во-первых, создайте функтор, как здесь.
>struct IdleConnFn :
> public std::unary_function
> bool operator() (const Conn& c) const { // чтобы он работал с
> if (с.getIdleTime() > TIMEOUT) { // другими объектами из
> return(true); //
> } else return(false);
> }
>} idle;
Затем вызовите >remove_if
с erase и передайте в него новый функтор, как здесь.
>vec.erase(std::remove_if(vec.begin(), vec.end(), idle), vec.end());
Есть причина, по которой такие функторы следует наследовать от >unary_function
, >unary_function
определяет несколько >typedef
, используемых другими функторами из >
, и если они их не найдут, то другие функторы не скомпилируются. Например, если вы очень злы и хотите удалить все не задействованные в данный момент соединения, то в функторе проверки на простой можно использовать функтор >not1
.
>vec.erase(std::remove_if(vec.begin(), vec.end(); std::not1(idle)),
> vec.end());
Наконец, вам может потребоваться сохранить первоначальную последовательность (может, с помощью >const
) и скопировать результаты, кроме некоторых элементов, в новую последовательность. Это можно сделать с помощью >remove_copy
и >remove_copy_if
, которые работают аналогично remove и >remove_if
, за исключением того, что здесь также требуется передавать >iterator
вывода, в который будут записываться результирующие данные. Например, чтобы скопировать из одного списка в другой строку, сделайте так.
>std::remove_copy(lstStr.begin(), lstStr.end(), lstStr2, "cloudy");
При использовании >remove_copy
или любого стандартного алгоритма, записывающего в выходной диапазон, следует помнить, что выходной диапазон должен уже быть достаточно большим, чтобы в нем поместились элементы, которые туда будут записываться.
>erase
и >remove
(и связанные с ними алгоритмы) предлагают удобный способ удалять определенные элементы последовательностей. Они предоставляют простую альтернативу самостоятельному перебору и поиску нужных элементов с последующим их удалением по одному.
Рецепты 6.2 и 7.1.
7.3. Случайное перемешивание данных
Имеется последовательность данных и требуется перемешать их так, чтобы они были расположены в случайном порядке.
Используйте стандартный алгоритм >random_shuffle
, определенный в >
. >random_shuffle
принимает два итератора произвольного доступа и (необязательно) функтор генератора случайных чисел и реорганизует случайным образом элементы заданного диапазона. Пример 7.3 показывает, как это делается.
Пример 7.3. Случайное перемешивание последовательностей
>#include
>#include
>#include
>#include
>#include "utils.h" // Для printContainer(): см. 7.10
>using namespace std;
>int main() {
> vector
> back_insert_iterator
> for (int i = 0; i < 10; ++i) *p = i;
> printContainer(v, true);
> random_shuffle(v.begin(), v.end());
> printContainer(v, true);
>}
Вывод должен выглядеть примерно так.
>-----
>0123456789
>-----
>8192057346
>random_shuffle
очень прост в использовании. Дайте ему диапазон, и он перемешает этот диапазон случайным образом. Имеется две версии, и их прототипы выглядят так.
>void random_shuffle(RndIter first, RndIter last);
>void random_shuffle(RndIter first, RndIter last, RandFunc& rand);
В первой версии используется зависящая от реализации функция генерации случайных чисел, которой должно быть достаточно для большинства задач. Если ее недостаточно — например, требуется неоднородное распределение, такое, как гауссово — то можно написать собственную функцию, которую можно передать во вторую версию.
Этот генератор случайных чисел должен быть функтором с единственным аргументом, возвращающим единственное значение, и оба они должны преобразовываться в
Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
Система сборки программ, используемая во FreeBSD, имеет значительно большие возможности, чем те, которые мы задействовали. Какие это возможности и как их использовать в своих портах?
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.
«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.