Реверсирование последовательности



 

В программах часто используется алгоритм reverse() , который в диапазоне, заданном параметрами start и end , меняет порядок следования элементов на противоположный. Его общий формат имеет следующий вид.

 

 

В следующей программе демонстрируется использование этого алгоритма.

 

 

Результаты выполнения этой программы таковы.

 

Преобразование последовательности

 

Одним из самых интересных алгоритмов является transform() , поскольку он позволяет модифицировать каждый элемент в диапазоне в соответствии с заданной функцией. Алгоритм transform() используется в двух общих форматах.

 

 

Алгоритм transform() применяет функцию к диапазону элементов и сохраняет результат в последовательности, заданной параметром result . В первой форме диапазон задается параметрами start и end . Применяемая для преобразования функция задается параметром unaryfunc . Она принимает значение элемента в качестве параметра и должна возвратить преобразованное значение. Во второй форме алгоритма преобразование выполняется с использованием бинарной функции, которая принимает в качестве первого параметра значение предназначенного для преобразования элемента из последовательности, а в качестве второго параметра – элемент из второй последовательности. Обе версии возвращают итератор, указывающий на конец результирующей последовательности.

В следующей программе используется простая функция преобразования xform() , которая возводит в квадрат каждый элемент списка. Обратите внимание на то, что результирующая последовательность сохраняется в том же списке, который содержал исходную последовательность.

 

 

При выполнении эта программа генерирует такие результаты.

 

 

Как видите, каждый элемент в списке x1 теперь возведен в квадрат.

 

Исследование алгоритмов

 

Описанные выше алгоритмы представляют собой только малую часть всего содержимого библиотеки STL. И конечно же, вам стоит самим исследовать другие алгоритмы. Заслуживают внимания многие, например set_union() и set_difference() . Они предназначены для обработки содержимого такого контейнера, как множество. Интересны также алгоритмы next_permutation() и prev_permutation() . Они создают следующую и предыдущую перестановки элементов заданной последовательности. Время, затраченное на изучение алгоритмов библиотеки STL, – это время, потраченное не зря!

 

Класс string

 

Класс string обеспечивает альтернативу для строк с завершающим нулем.

Как вы знаете, C++ не поддерживает встроенный строковый тип. Однако он предоставляет два способа обработки строк. Во‑первых, для представления строк можно использовать традиционный символьный массив с завершающим нулем. Строки, создаваемые таким способом (он вам уже знаком), иногда называют С‑строками . Во‑вторых, можно использовать объекты класса string , и именно этот способ рассматривается в данном разделе.

В действительности класс string представляет собой специализацию более общего шаблонного класса basic_string . Существует две специализации типа basic_string : тип string , который поддерживает 8‑битовые символьные строки, и тип wstring , который поддерживает строки, образованные двухбайтовыми символами. Чаще всего в обычном программировании используются строковые объекты типа string . Для использования строковых классов C++ необходимо включить в программу заголовок <string> .

Прежде чем рассматривать класс string , важно понять, почему он является частью С++‑библиотеки. Стандартные классы не сразу были добавлены в определение языка C++. На самом деле каждому нововведению предшествовали серьезные дискуссии и жаркие споры. При том, что C++ уже содержит поддержку строк в виде массивов с завершающим нулем, включение класса string в C++, на первый взгляд, может показаться исключением из этого правила. Но это далеко не так. И вот почему: строки с завершающим нулем нельзя обрабатывать стандартными С++‑операторами, и их нельзя использовать в обычных С++‑выражениях. Рассмотрим, например, следующий фрагмент кода.

 

 

Как отмечено в комментариях, в C++ невозможно использовать оператор присваивания для придания символьному массиву нового значения (за исключением инструкции инициализации), а также нельзя применять оператор "+" для конкатенации двух строк. Эти операции можно выполнить с помощью библиотечных функций.

 

 

Поскольку символьный массив с завершающим нулем формально не является самостоятельным типом данных, к нему нельзя применить С++‑операторы. Это лишает "изящества" даже самые элементарные операции со строками. И именно неспособность обрабатывать строки с завершающим нулем с помощью стандартных С++‑операторов привела к разработке стандартного строкового класса. Вспомните: создавая класс в C++, мы определяем новый тип данных, который можно полностью интегрировать в С++‑среду. Это, конечно же, означает, что для нового класса можно перегружать операторы. Следовательно, вводя в язык стандартный строковый класс, мы создаем возможность для обработки строк так же, как и данных любого другого типа, а именно посредством операторов.

Однако существует еще одна причина, оправдывающая создание стандартного класса string : безопасность. Руками неопытного или неосторожного программиста очень легко обеспечить выход за границы массива, который содержит строку с завершающим нулем. Рассмотрим, например, стандартную функцию копирования strcpy() . Эта функция не предусматривает механизм проверки факта нарушения границ массива‑приемника. Если исходный массив содержит больше символов, чем может принять массив‑приемник, то в результате этой ошибки очень вероятен полный отказ системы. Как будет показано ниже, стандартный класс string не допускает возникновения подобных ошибок.

Итак, существует три причины для включения в C++ стандартного класса string : непротиворечивость данных (строка теперь определяется самостоятельным типом данных), удобство (программист может использовать стандартные С++‑операторы) и безопасность (границы массивов отныне не будут нарушаться). Следует иметь в виду, что все выше перечисленное не означает, что вы должны отказываться от использования обычных строк с завершающим нулем. Они по‑прежнему остаются самым эффективным средством реализации строк. Но если скорость не является для вас определяющим фактором, использование нового класса string даст вам доступ к безопасному и полностью интегрированному способу обработки строк.

И хотя класс string традиционно не воспринимается как часть библиотеки STL, он, тем не менее, представляет собой еще один контейнерный класс, определенный в C++. Это означает, что он поддерживает алгоритмы, описанные в предыдущем разделе. При этом строки имеют дополнительные возможности. Для получения доступа к классу string необходимо включить в программу заголовок <string> .

Класс string очень большой, он содержит множество конструкторов и функций‑членов. Кроме того, многие функции‑члены имеют несколько перегруженных форм. Поскольку в одной главе невозможно рассмотреть все содержимое класса string , мы обратим ваше внимание только на самые популярные его средства. Получив общее представление о работе класса string , вы сможете легко разобраться в остальных его возможностях самостоятельно.

Прототипы трех самых распространенных конструкторов класса string имеют следующий вид.

 

 

Первая форма конструктора создает пустой объект класса string . Вторая форма создает string ‑объект из строки с завершающим нулем, адресуемой параметром str . Эта форма конструктора обеспечивает преобразование из строки с завершающим нулем в объект типа string . Третья создает string ‑объект из другого string ‑объекта.

Для объектов класса string определены следующие операторы.

 

 

Эти операторы позволяют использовать объекты типа string в обычных выражениях и избавляют программиста от необходимости вызывать такие функции, как strcpy() или strcat() . В общем случае в выражениях можно смешивать string ‑объекты и строки с завершающим нулем. Например, string ‑объект можно присвоить строке с завершающим нулем.

Оператор "+" можно использовать для конкатенации одного string ‑объекта с другим или string ‑объекта со строкой, созданной в С‑стиле (С‑строкой). Другими словами, поддерживаются следующие операции.

 

 

Оператор "+" позволяет также добавлять символ в конец строки.

В классе string определена константа npos , которая равна ‑1 . Она представляет размер строки максимально возможной длины.

Строковый класс C++ существенно облегчает обработку строк. Например, используя string ‑объекты, можно применять оператор присваивания для назначения string ‑объекту строки в кавычках, оператор "+" – для конкатенации строк и операторы сравнения – для сравнения строк. Выполнение этих операций демонстрируется в следующей программе.

 

 

При выполнении эта программа генерирует такие результаты.

 

 

Обратите внимание на то, как легко теперь выполняется обработка строк. Например, оператор "+" используется для конкатенации строк, а оператор ">" – для сравнения двух строк. Для выполнения этих операций с использованием С‑стиля обработки строк, т.е. использования строк с завершающим нулем, пришлось бы применять менее удобные средства, а именно вызывать функции strcat() и strcmp() . Поскольку С++‑объекты типа string можно свободно смешивать с С‑строками , их (string ‑объекты) можно использовать в любой программе не только безо всякого ущерба для эффективности, но даже с заметным выигрышем.

Важно также отметить, что в предыдущей программе размер строк не задается. Объекты типа string автоматически получают размер, нужный для хранения заданной строки. Таким образом, при выполнении операций присваивания или конкатенации строк строка‑приемник увеличится по длине настолько, насколько это необходимо для хранения нового содержимого строки. При обработке string ‑объектов невозможно выйти за границы строки. Именно этот динамический аспект string ‑объектов выгодно отличает их от строк с завершающим нулем (которые часто страдают от нарушения границ).

 

Обзор функций‑членов класса string

 

Если самые простые операции со строками можно реализовать с помощью операторов, то при выполнении более сложных не обойтись без функций‑членов класса string . Класс string содержит слишком много функций‑членов, мы же рассмотрим здесь только самые употребительные из них.

Важно! Поскольку класс string– контейнер, он поддерживает такие обычные контейнерные функции, как begin(), end() и size().

 


Дата добавления: 2018-09-22; просмотров: 335; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!