//
fill_n(back_inserter(vec), 10, 0); //
На каждой итерации функция fill_n() присваивает элемент заданной последовательности. Поскольку ей передается итератор, возвращенный функцией back_inserter(), каждое присвоение вызовет функцию push_back() вектора vec. В результате этот вызов функции fill_n() добавит в конец вектора vec десять элементов, каждый со значением 0.
copy()Алгоритм copy() — это еще один пример алгоритма, записывающего элементы последовательности вывода, обозначенной итератором назначения. Этот алгоритм получает три итератора. Первые два обозначают исходный диапазон, а третий — начало последовательности вывода. Этот алгоритм копирует элементы из исходного диапазона в элементы вывода. Важно, чтобы переданный функции copy() контейнер вывода был не меньше исходного диапазона.
В качестве примера используем функцию copy() для копирования одного встроенного массива в другой:
int a1[] = {0,1,2,3,4,5,6,7,8,9};
int а2[sizeof(a1)/sizeof(*a1)]; //
//
auto ret = copy(begin(a1), end(a1), a2); // копирует a1 в a2
Здесь определяется массив по имени a2, а функция sizeof() используется для гарантии равенства размеров массивов а2 и a1 (см. раздел 4.9). Затем происходит вызов функции copy() для копирования массива a1 в массив а2. После вызова у элементов обоих массивов будут одинаковые значения.
Возвращенное функцией copy() значение является приращенным значением ее итератора назначения. Таким образом, итератор ret укажет на следующий элемент после последнего скопированного в массив а2.
Некоторые алгоритмы обладают так называемой версией "копирования". Эти алгоритмы осуществляют некую обработку элементов исходной последовательности, но саму последовательность не изменяют. Они могут создавать новую последовательность, в которую и сохраняют результат обработки элементов исходной.
Например, алгоритм replace() читает последовательность и заменяет каждый экземпляр заданного значения другим значением. Алгоритм получает четыре параметра: два итератора, обозначающих исходный диапазон, и два значения. Он заменяет вторым значением значение каждого элемента, которое равно первому.
//
replace(ilst.begin(), ilst.end(), 0, 42);
Этот вызов заменяет все экземпляры со значением 0 на 42. Если исходную последовательность следует оставить неизменной, необходимо применить алгоритм replace_copy(). Этой версии функции передают третий аргумент: итератор, указывающий получателя откорректированной последовательности.
//
//
replace_copy(ilst.cbegin(), ilst.cend(),
back_inserter(ivec), 0, 42);
После этого вызова список ilst останется неизменным, а вектор ivec будет содержать копию его элементов, но со значением 42 вместо 0.
Некоторые алгоритмы изменяют порядок элементов в пределах контейнера. Яркий пример такого алгоритма — sort(). Вызов функции sort() упорядочивает элементы исходного диапазона в порядке сортировки, используя оператор < типа элемента.
Предположим, необходимо проанализировать слова, использованные в наборе детских рассказов. Текст рассказов содержится в векторе. Необходимо сократить этот вектор так, чтобы каждое слово присутствовало в нем только один раз, независимо от того, сколько раз оно встречается в любом из данных рассказов.
Для иллюстрации поставленной задачи используем в качестве исходного текста следующую простую историю:
the quick red fox jumps over the slow red turtle
В результате обработки этого текста программа должна создать следующий вектор:
Для устранения повторяющихся слов сначала отсортируем вектор так, чтобы дубликаты располагались рядом друг с другом. После сортировки вектора можно использовать другой библиотечный алгоритм, unique(), чтобы расположить уникальные элементы в передней части вектора. Поскольку алгоритмы не могут работать с самими контейнерами, используем функцию-член erase() класса vector для фактического удаления элементов: