7.9. Преобразование элементов последовательности
7.9. Преобразование элементов последовательности
Проблема
Имеется последовательность элементов, и с каждым элементом требуется выполнить какие-либо действия — либо на месте, либо скопировав их в другую последовательность.
Решение
Используйте стандартные алгоритмы transform или for_each. Они оба просты, но позволяют выполнить почти любые действия с элементами последовательностей. Пример 7.9 показывает, как это делается.
Пример 7.9. Преобразование данных
#include <iostream>
#include <istream>
#include <string>
#include <list>
#include <algorithm>
#include <iterator>
#include <cctype>
#include "utils.h" // Для printContainer(): см. 7.10
using namespace std;
// Преобразуем строки к верхнему регистру
string strToUpper(const string& s) {
string tmp;
for (string::const_iterator p = s.begin(); p != s.end(); ++p)
tmp += toupper(*p);
return(tmp);
}
string strAppend(const string& s1, const string& s2) {
return(s1 + s2);
}
int main() {
cout << "Введите несколько строк: ";
istream_iterator<string> start(cin);
istream iterator<string> end;
list<string> lst(start, end), out;
// Используем преобразование с помощью унарной функции...
transform(lst.begin(), lst.end(), back_inserter(out),
strToUpper);
printContainer(out);
cin.clear();
cout << Введите другой набор строк: ";
list<string> lst2(++start, end);
out.clear();
// ...или бинарную функцию и другую входную последовательность
transform(lst.begin(), lst.end(), lst2.begin(),
back_inserter(out), StrAppend);
printContainer(out);
}
Обсуждение
Очевидно, что для преобразования данных используется transform. Он имеет две формы. Первая форма принимает последовательность, итератор вывод и унарный функтор. Он применяет функтор к каждому элементу последовательности и присваивает возвращаемое значение следующему значению, на которое указывает итератор вывода. Итератор вывода может быть другой последовательностью или началом оригинальной последовательности. В этом отношении transfоrm может выполнять преобразование как «на месте», так и копируя результат в другую последовательность.
Вот как выглядит объявление transform.
Out transform(In first, In last, Out result, UnFunc f);
Out transform(In first1, In last1, In first2, In last2,
Out result, BinFunc f);
Обе версии возвращают итератор, который указывает на один после конца результирующей последовательности.
Использование обеих версий очень просто. Чтобы скопировать строку из одной последовательности в другую, но с преобразованием ее к верхнему регистру, сделайте так, как в примере 7.9.
std::transform(lst.begin(), lst.end(),
std::back_inserter(out), strToUpper);
Если требуется изменить первоначальную последовательность, просто передайте в качестве результирующего итератора начало этой последовательности.
std::transform(lst.begin(), lst.end(),
lst.begin(), strToUpper);
Использование двух последовательностей и бинарной операции работает точно так же. и в качестве выходной последовательности можно использовать одну из входных.
Если требуется преобразовать элементы на месте, можно избежать накладных расходов на присвоение каждому элементу возвращаемого значения некоторой функции. Или, если функтор, который требуется использовать, изменяет свой объект-источник, то можно использовать for_each.
void strToUpperInPlace(string& s) {
for (string::iterator p = s.begin(); p != s.end(); ++p)
*p = std::toupper(*p);
}
// ...
std::for_each(lst.begin(), lst.end(), strToUpperInPlace);
Если же все, что требуется сделать, — это изменить саму последовательность, не изменяя каждый из ее элементов, то в рецепте 7.6 описывается множество стандартных алгоритмов для реорганизации элементов в последовательностях.
Смотри также
Рецепты 7.1 и 7.6.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
21.3.2. Управляющие последовательности
21.3.2. Управляющие последовательности Существуют несколько отдельных типов управляющих последовательностей. Самый простой тип представляет собой символ перехода (^[), за которым следует один командный символ. (Несмотря на то что символ перехода отображается в строках С
21.3.4. Составные управляющие последовательности
21.3.4. Составные управляющие последовательности Пять двухсимвольных управляющих последовательностей (которые показаны в табл. 21.3) фактически являются префиксами более длинных и сложных последовательностей. Рассмотрим каждую из них по очереди.Таблица 21.3. Составные
Добавление новых элементов в панель элементов управления
Добавление новых элементов в панель элементов управления Чтобы получить возможность использовать элемент управления ActiveX, выполните следующее.1. Установите программное обеспечение элемента управления на жесткий диск.Мне кажется, это имеет смысл.2. Зарегистрируйте
2.33. Генерирование последовательности строк
2.33. Генерирование последовательности строк Изредка бывает необходимо получить «следующую» строку. Так, следующей для строки "aaa" будет строка "aab" (затем "aac", "aad" и так далее). В Ruby для этой цели есть метод succ:droid = "R2D2"improved = droid.succ # "R2D3"pill = "Vitamin B"pill2 = pill.succ # "Vitamin C"He
Числовые последовательности
Числовые последовательности Вот две известные в информатике головоломки. Сожалею, что обманываю ожидания своих коллег, которые не найдут здесь ничего нового…?* Головоломка 5. Последовательность Хэмминга.Рассмотрим числа, не имеющие других простых делителей, кроме 2, 3 и 5.
Управляющие последовательности
Управляющие последовательности Как и в других языках, подобных C, строковые литералы в C# могут содержать различные управляющие последовательности, которые интерпретируются как определенный набор данных, предназначенных для отправки в выходной поток. Каждая
Хранение элементов в коллекциях и получение элементов из коллекций
Хранение элементов в коллекциях и получение элементов из коллекций Коллекции — это такие объекты, в экземплярах которых могут храниться другие объекты. Одна из самых распространенных разновидностей коллекций — это массив, который инстанцирует NSArray или NSMutableArray. В
Последовательности (Sequences)
Последовательности (Sequences) Последовательность - это вид контейнера, который организует конечное множество объектов одного и того же типа в строгом линейном порядке. Библиотека обеспечивает три основных вида последовательных контейнеров: vector (вектор), list (список) и deque
Преобразование последовательных элементов в параграфы.
Преобразование последовательных элементов в параграфы. 1. Кликните дважды на первый элемент.2. Удерживая Shift, кликните на последний элемент.3. Кликните правой кнопкой мышки внутри основного окна BookDesigner и затем нажмите "more transformations"-" "selected elements -"
Последовательности
Последовательности Последовательность - это набор данных, которые можно перебрать один за другим в некотором порядке. К разновидностям последовательностей относятся одномерные динамические массивы array of T, списки List<T>, двусвязные списки LinkedList<T>, множества
Последовательности команд
Последовательности команд Часто для выполнения определенного действия пользователь должен по очереди раскрывать несколько пунктов меню. Например, чтобы запустить в Windows Vista программу Блокнот, нужно выполнить следующие действия.1. Нажать кнопку Пуск.2. Выбрать пункт Все