|
Программирование >> Разработка устойчивых систем
int mainO { vector<Inventory> vi: srand(time(0)): Randomize generate n(back inserter(vi). 15. InvenGenO): printCvi .beginO. vi.endO. vi ): InvAccum ia = for each(vi .beginO.vi .endO. InvAccumO): cout ia endl: } /:- Операторная функция operator() класса InvAccum вызывается с одним аргументом, как того требует алгоритм for each(). По мере перебора элементов интервала алгоритм for each() берет каждый элемент и передает его операторной функции InvAccum::operator(), где производятся вычисления и сохраняется результат. В конце перебора for each() возвращает объект InvAccum, и содержимое этого объекта выводится на печать. Многие операции с объектами Inventory могут вьшолняться алгоритмом for each(). Например, for each() позволяет легко поднять все цены на 10 %. Однако стоит обратить внимание, что объекты Inventory не позволяют изменить значение item -программист, разработавший Inventory, решил, что так будет безопаснее. Да и кому может понадобиться изменять название товара? Но вдруг коммерческий отдел решил, что для придания товару нового, улучшенного вида нужно преобразовать все названия к верхнему регистру. Специалисты провели исследования, которые показали, что смена названия приведет к росту продаж (надо же коммерческому отделу лгошь что-то делать...). В этой ситуации алгоритм for each() не работает, но зато поможет алгоритм transform(): : СОб:TransformNames.срр Пример использования transformO #include <algorithm> #i nclude <cctype> #i nclude <ctime> #i nclude <vector> #include Inventory.h #include PrintSequence.h using namespace std: struct Newlmproved { Inventory operatorO(const InventoryS inv) { return Inventory(toupper(inv.getItem()). i nv.getQuantity(). inv.getVal ueO): int mainO { vector<Inventory> vi: srandCtimeCO)): Раскрутка генератора случайных чисел generate n(back inserter(vi). 15. InvenGenO): print(vi .begin(). vi.endO. vi ): transform(vi .beginO. vi.endO. vi.beginO. NewImprovedO): print(vi .begin(). vi.endO. vi ): ) /:- . total value: 1а.value: struct DiscGen { float operatorOO { float r = float(rand() % 10): return r / 100.0: int mainO { vector<Inventory> vi: srand(t1me(0)): Раскрутка генератора случайных чисел generate n(back inserter(vi), 15. InvenGenO): pr1nt(v1 .beginO. vi.endO. vi ): vector<float> disc: generate n(back inserter(disc). 15. DiscGenO): print(disc.beginO. disc.endO. Discounts: ): vector<Inventory> discounted: transform(vi .beginO.vi .endO. disc.beginO. back i nserter(di scounted). Di scounter()): pri nt(d1scounted. begi nO. di scounted. endO. discounted ): } /:- Объект функции Discounter строит для заданного объекта Inventory и процента скидки новый объект Inventory со сниженной ценой. Объект функции DiscGen просто генерирует случайные величины скидок от 1 до 10 %, используемые в нашем тесте. В функции main() создаются два вектора: для объектов Inventory и для скидок. Эти объекты передаются алгоритму transform() вместе с объектом Discounter, а алгоритм transform() заполняет новый вектор vector<Inventory> с именем discounted. Числовые алгоритмы Числовые алгоритмы определяются в заголовочном файле <numeric>, поскольку они используются в основном для выполнения математических вычислений. Обратите внимание: приемный интервал совпадает с исходным интервалом, то есть преобразование выполняется на месте . Теперь предположим, что отдел сбыта захотел сгенерировать специальные ценники с разными скидками по каждой позиции. Исходный список должен остаться без изменений, но при этом нужно сгенерировать несколько специальных списков. Отдел сбыта предоставил список скидок для каждого нового списка. Задача решается при помощи второй формы алгоритма transforni(): : СОб:Special List.срр Пример использования второй формы transformO finclude <algorithm> ilnclude <ct1me> #1nclude <vector> #1nclude Inventory.h #1nclude PrintSequence.h using namespace std: struct Discounter { Inventory operatorO(const InventoryS inv. float discount) { return InventoryOnv.getltemO. Inv.getQuantityO. Int(Inv.getValueO * (1 - discount))): Т accumulate(Inputlterator first. Inputlterator last. T result); T accumulate(Inputlterator first. Inputlterator last, T result, BinaryFunction f); Первая форма реализует обобщенное суммирование. Для каждого элемента [firstlast), на который ссылается итератор i, выполняется операция result result + *i, где result относится к типу Т. Вторая форма имеет более общий характер: она применяет функцию f(result*i) к каждому элементу *i от начала до конца интервала. Обратите внимание на сходство между вторыми формами алгоритмов transform() и accumulate(). Т inner product(Inputlteratorl firstl. Inputlteratorl lastl. InputIterator2 first2, T init); T inner product(Inputlteratorl firstl, Inputlteratorl lastl. InputIterator2 f1rst2, T Init, BinaryFunctionl opl, B1naryFunct1on2 op2); Алгоритм вычисляет обобщенное скалярное произведение двух интервалов [firstl,lastl) и [first2,first2+(lastl-firstl)). Возвращаемое значение определяется умножением элементов первого интервала на параллельные элементы второго интервала и прибавлением результата к накапливаемой сумме. Таким образом, для двух интервалов {1,1,2,2} и {1,2,3,4} скалярное произведение равно (1*1) + (1*2) + (2*3) + (2*4) = 17 Аргумент init содержит начальное значение накапливаемой суммы. Обычно оно равно нулю, но вы можете задать любое другое значение. Начальное значение особенно важно при пустом первом интервале, потому что оно становится возвращаемым значением. Второй интервал должен содержать как минимум не меньще элементов, чем первый. Вторая форма просто вызывает пару функций для переданных интервалов. Функция opl используется вместо сложения, а ор2 заменяет умножение. Таким образом, вторая версия inner product() в приведенном примере выполняет следующие операции: init = opKinit, ор2(1.1)); init = opKinit, ор2(1.2)); init = opKinit, op2(2,3)); init = opKinit, op2(2,4)): Происходящее напоминает работу алгоритма transform(), но с выполнением двух операций вместо одной. Outputlterator part1al sum(Inputlterator first. Inputlterator last, Outputlterator result); Outputlterator partial sum(Inputlterator first. Inputlterator last, Outputlterator result. BinaryFunction op); Алгоритм вычисляет обобщенную частичную сумму и создает новый интервал, начинающийся с result. Значение п-го элемента этого интервала равно сумме всех элементов интервала [firstlast) от 1 до п. Например, для исходной последовательности {1,1,2,2,3} генерируется последовательность {1,1 + 1,1 +1 + + 2,1 +1 +2 +2,1 +1 +2 +2 + 3}, то есть {1,2,4,6,9}. Во второй форме алгоритма вместо оператора + используется бинарная функция ор. Она получает накопленное значение и объединяет его с текущим элементом. Например, если задействовать объект multiplies<int>() с предшествую-
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |