Г. Шилдт - Полный справочник по C++ (1109478), страница 99
Текст из файла (страница 99)
Взпс1нде <хозегеаш> а1пс1нз)е <чессог> Мхпс1нбе <а1догхснш> нзхпд пашеврасе ве()з хпс юахп() спаг вег(] = "Шаблон БТЬ обладает большой мощью. чесеог<снаг> ч, ч2(30)з 1пс Оог(1=Оз ест[1]з х++) ч.рнвЬ Ьаск(всг(х))з // **** Демонстрация алгоритма гешоче сору "*** сонг. « "Исходная последовательность:1п"з 1ог(з=О," з<ч.вххе()з х++) соне « ч[1)з сонг « епд1з // Удаляем все пробелы. геточе сору(ч.Ьедхп(!, ч.епб(), ч2.Ьедхп(), ' ')з соне « "Результат после удаления пробеловз 1п"з гог(з.=Оз з<ч2.яхве()з з.++] сонг.
« ч2[1]з соне « епб1 « епд1з // ***я Демонстрация алгоритма гер1асе сору **** сонг « "исходная последовательностьз 1п"; Оог(1=-Оз 1<ч.в1те[)з 1++) соне « ч[1); сонг « епб1з // Заменяем пробелы двоеточиями гер1асе сору(ч.Ьедхп(), ч.епб(), ч2.Ьедхп() соне « "'Результат после замены гробелов двоеточиямиз1п"; Оог (х=Оз 1<ч2 . з1хеО з х++) соне « ч2 [х) з сонг « епб1 « епд1з гегнгп 0; ) Результат работы этой программы привелен ниже.
исходная последовательность: Библиотека БТЬ обладает большой мощью. Результат после удаления пробелов: БиблиотекаБТ(.обладаетбольшоймощью. Исходная последовательность: Библиотека ЗТЬ обладает большой мощью. Результат после удаления пробелов: Библиотека:ЗТЬзобладает:большойзмощью. Часть П. Язык С++ Изменение порядка следования элементов последовательности Для изменения порядка следования элементов послеловательностн на обратный применяется алгори~м течегве().
Его спецификация имеет следую>ций вид. В се>пр1асе <с1авв В11сет> чей течехве(вттсег пап, в11сет еят() > Алгоритм гечегве()изменяет порядок следования элементов в диапазоне между итераторами згаг( и ел>т' нв обратный. Проиллюстрируем алгоритм хечетве() слелуюшей программой. г'г' Демонстрация алгоритма хечехяе. В1пс1ис)е <1оясгеатп> «1пс1ит)е <честит> 41пс1иде <а1дот1С)пп> ив1пд па>певрасе вст)> >пс тпаъп() чессот<1пс> чт >пс 1> лот(1=0> т<10> т++) ч.рия)> )таси(1) соис « "Исходная последовательность> лот(т=0> т<ч.вате()> 1++) соис « ч(1) « соис « епт)1> хечехяе(ч.седло(), ч.еп()О ) соих « "Обратная последовательность: лот(1=0> 1<ч.втяе()> т++) соиС « ч(т) « теситп 0; ) Результаты ее работы выглялят так. Исходная последовательность: 0 1 2 3 4 5 б 7 0 9 Обратная последовательность: 9 6 7 б 5 4 3 2 1 0 Преобразование последовательности Один из самых интересных алгоритмов — сгапвлотв>() — модифицирует кажлый элемент заданного диапазона с помошью функции, заданной программистом.
Алгоритм сгепвеогм() имеет лве разновидности. сея>р1асе <с1авв 1п1сех, с1авв Оис1сех, с1авв Рипс, Оис1сег стапвбохп>(1п1сет лаг>, 1п1сет еят), Оистсет гет>г(>, Рипс ияаг)гаг>е) т сетпр1асе <с1авв 1п1сех1, с1авв 1п1сех2, с1авв Оис1сет, с1авв Рипа, Оистсех стапвбох>п(1птсет1 т>агт), 1п1сех1 егн(), 1птсег2 лаг>2, Оисггет гетнлс Риис Ьтаг>)>им) > Этот алгоритм применяет функцию ко всем элементам заланного лиапазона и сохраняет результат в объекте генг)т.
В первом варианте диапазон определяется итераторами з(агг и ел>т', функция залается параметрол> алаг)уяяс. Она получает значения элементов Глава 24. Введение в стандартнуе библиотеку шаблонов своего параметра и возвращает преобразованную последовательность. Во в~ором варианте преобразование последовательности выполняется функтором 6/лагфглс. Первым параметром этой функции является значение элемента из этой последовательности, а вторым — элемент из второй последовательности. Обе версии функции ееапвдохзеО возвращают итеразор, ссылающийся на конец результирующей последовательное~и.
Следующая программа использует для преобразования последовательное~и простую функцию ееедреоса1(), которая заменяет числа, входящие в список, обратными величинами. Обратите внимание на то, что результирующая последовательность записывается в исходный список. // Пример преобразования последовательности. З?пс1цде <?ов?теащ> Ю1пс1цбе <1?в?> З?пс1цдо <а1дот??нт> цвьпд пащеврасе в?б; // Простая функция, задающая преобразование. <)оцЫе тес1ртоса1(боцЫе 1) ( тегцтп 1.0/1; // Возвращает обратное число.
теецтп тес?ртоса1 1пс щагп() ( 1?вс<доцЬ1е> ча1в; гпс 1/ // Занести число в список. тот( 1=1; 1<10; 1++) ча1в .рцвн Ьас? ((боцЫе) 1]; соне « "Исходное содержимое списка ча1в:хп"; 11вс<боцЫе>::?седа?от р = ча1в.Ьед?п(); ин?1е(р != ча1в.епб()) ( сова « *р « р++," соцс «епс)1; // Преобразование списка ча1в. р =- стапвтотщ(ча1в.Ьедтп(), ча1в.епдО, ча1в.?ед1п(), тестртоса1) соц? « "Преобразованное содеряжмое списка ча1вг то"; р = ча1в.Ьедзп(); ин?1е(р != ча1в.епбО ) соцс « *р « р'Н ) тесцтп О; ) Результат работы этой программы показан ниже. Исходное содержимое списка ча1в: 1 2 3 4 5 б 7 8 9 Преобразованное содержимое списка ча1в: 1 0.5 0.33333 0.25 0.2 0.166667 0.142857 0.125 0.111Ш Часть Н.
Язык С++ ~~ Применение функторов Как указывалось в начале главы, библиотека В'П. интенсивно использует функторы. Напомним, что функтор — это класс, в котором определена операторная функция оресаеое(). Библиотека ЯТ). содержит большое количество встроенных функторов, например, 1еве, за1пие и др. Она позволяет также определять свои собственные функторы. Честно говоря, в задачу нашей книги не входит полное описание процесса создания и применения функторов.
К счастью, как показывают прелылушие примеры, библиотеку ВТ(. можно применять, не прибегая к помоши функторов. Однако, поскольку функторы являются основным компонентом библиотеки ЯТ(., важно понимать, как они работают. Унарные и бинарные функторы Подобно унарным и бинарным преликатам, сушествуюз унарные и бинарные функ- торы. Унарный функтор имеет один аргумент, а бинарный — два. Унарный и бинарный функторы не могут заменять друг друга. Например, если алгоритм использует бинарный функтор, ему нужно передавать именно бинарный, а не унарный функтор.
Применение встроенных функторов В библиотеке ВТ(. прелусмотрен широкий выбор встроенных функторов. Перечислим бинарные функторы. аШпзв зюе есиа1 Со 1овасе1 ап(( 1аее зпоаи1ив Вееасек е((иа1 1еав р1ие епиа1 Ео 1евв е((иа1 К унарным относятся следуюшие функторы. 1одаса1 пос Для вызова встроенных функторов в программу необходимо включи~ь заголовок <хиисеаопа1>. Рассмотрим простой пример. Следуюшая программа использует алгоритм сеапвЕокв(), описанныи в прелылушем разделе, и функтор педасе() для изменения знака значений, перечисленных в списке.
// Применение унарного функтора. Е1пс1ис)е <1оаегеааг атпс1ис)е <11ат> «ьпс1ис)е <сипсеаопа1> Вгпс1иг)е <а1яогесвп> ияапя паюеарасе аес); апс гоа1п() ( 11а с<с)ои)>1е> иа1а," апс 1; Глава 24. Введение в стандартную библиотеку шаблонов Функторы выполняют операции, определенные их именами. Елинственное имя, которое не является самоочевилным, — название функгора певеке(), изменяюшего знак своего аргуменза. Встроенные функторы являются шаблонными классами, в которых перегружен оператор (), возврашаюший результат выбранной операции. Например, чтобы применить бинарный функтор р1ие() к ланным типа Е1оае, следует использовать следуюшую синтаксическую конструкцию. )) р1иа<Е1оас> О // Заносим значения в список. гог(1=-1» 1<10; 1.н-) ча1в.ровп Ьас)с((йоиЫе)1); сонг « "Исходное содержимое списка ча1вг чп"г 11вг<йоиЫе>»: фгегагог р = ча1в.Ьедфп(); ыЬ11е(р != ча1в.епй(!) ( соиг « *р « !»++; соог «епс(1; // Применение функтора педаге.
р = ггапвгоггл(ча1в.Ьедьп(), ча1в.епй(), ча1в.Ьедгп() . педаге<йоиЬ1е>())» // Вызываем функтор. соис « "Измененное содержимое списка ча1в» хп"» р = ча1в.Ьвдьп()г нп11е(р != ча1в.епй()) сонг « *р « ~Н.+» ) гегогп О; ) Программа выводит на экран следующие результаты, »» Исходное содержимое списка ча1в: 1 2 3 4 5 б 7 8 9 О Измененное содержимое списка ча1в» -1 -2 -3 -4 -5 /б -7 — 8 — 9 -0 Обратите внимание на то, как в этой программе вызывается функтор педаее(). Поскольку список ча1в хранит числа типа йочые, функтор педаее() вызывается с помощью конструкиии педаее<йочЬ1е>().
Алгоритм егапвгогм() автоматически применяет функтор педаге() к каждому элементу последовательности. Таким образом, единственный параметр функтора педаге() является элементом последовательности. Следующая программа демонсп»ирует применение бинарного функтора й1чьйевО. Она создает два списка действительных чисел и делит значения одного списка на значения другого. Для этого используется бинарная форма алгоритма егапвдохта(). // Применение бинарного функтора. Зьпс1ойе <ьовсгеагл> агпс1ийе <11вг> дьпс1ойе <йопсгфопа1> аьпс1ийе <а1дог1ГЬ»п> ивьпд паглеврасе вгй» ьпг гааза() 11в <йоиЫе> ча1в» 11вг<с1ооЫе> йтчзвогв» гпг // Заносим значения в список. бог(1=10» 1<100; 1+=10) ча1в.ривЬ Ьас)с((йоцЫе)1); гог(1=1» (<10» 1++) йгч1вогв.рави Ьасх(3.0)г Часть ().
Язык С++ сои» « "исходное значение списка ча1в> хп"; 1?я?<»)оиЬ?е>:".1?етатот р = ча1в.ЬедЫ (); ьи?1е(р ]= ча1в.епс)()) ( сои? « *р « р++] сои» «еп»)1; Преобразование списка ча1в. р = ттапвботп(ча1в.Ьед?п(), ча1в.еп»)(), »)1ч?яств.?едтп(), ча1в.Ьед?п(), е)?чЫея<боиЬ|е>()]; // Вызываем функтор. сои? « "Измененное содержимое списка ча1в>хп"; р = ча1в.Ьед?п(]; ыЬ).1е(р ]= ча1в.епс)()) ( сои? « *р « р++; ) тесптп 0: ) Программа выводиз.