Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

equal
сравнивает две последовательности на равенство. Имеется две версии: одна использует
operator==
, а другая использует переданный ей функциональный объект двоичного предиката (т.е. такой, который принимает два аргумента и возвращает
bool
). В примере 4.21
caseInsCharCompareN
и
W
— это функции двоичного предиката.

Но это не всё, что требуется сделать; также требуется сравнить размеры. Рассмотрим объявление

equal
.

template<typename InputIterator1, typename InputIterator2,

 typename BinaryPredicate>

bool equal(InputIterator1 first, InputIterator1 last1,

 InputIterator2 first2, BinaryPredicate pred);

Пусть n

это расстояние между
first1
и
last1
, или, другими словами, длина первого диапазона.
equal
возвращает
true
, если первые
n
элементов обеих последовательностей равны. Это означает, что если есть две последовательности, где первые
n
элементов равны, но вторая содержит больше чем
n
элементов, то
equal
вернет
true
. Чтобы избежать такой ошибки требуется проверять размер.

Эту логику не обязательно инкапсулировать в функцию. Ваш или клиентский код может просто вызвать алгоритм напрямую, но проще запомнить и написать такое:

if (caseInsCompare(s1, s2)) { // они равны, делаем что-нибудь

чем такое:

if ((s1.size == s2.size) &&

std::equal(s1.begin, s1.end(s2.begin, caseInsCharCompare<char>)) {

 // они равны, делаем что-нибудь

когда требуется выполнить сравнение строк без учета регистра.

4.14. Выполнение поиска строк без учета регистра

Проблема

Требуется найти в строке подстроку, не учитывая разницу в регистре.

Решение

Используйте стандартные алгоритмы

transform
и
search
, определенные в
<algorithm>
, а также свои собственные функции сравнения символов, аналогичные уже показанным. Пример 4.22 показывает, как это делается.

Пример 4.22. Поиск строк без учета регистра

#include <string>

#include <iostream>

#include <algorithm>

#include <iterator>

#include <cctype>

using namespace std;

inline bool caseInsCharCompSingle(char a. char b) {

 return(toupper(a) == b);

}

string::const_iterator caseInsFind(string& s, const string& p) {

 string tmp;

 transform(p.begin, p.end, // Преобразуем шаблон

back_inserter(tmp), // к верхнему регистру

toupper);

 return(search(s.begin, s.end, // Возвращаем итератор.

tmp.begin, tmp.end, //
возвращаемый из

caseInsCharCompSingle)); // search

}

int main {

 string s = "row, row, row, your boat";

 string p = "YOUR";

 string::const_iterator ir = caseInsFind(s, p);

 if (it != s.end) {

cout << "Нашли!\n;

 }

}

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

Обсуждение

Пример 4.22 демонстрирует обычный ход действий при работе со стандартными алгоритмами. Создайте функцию, которая выполняет работу, а затем подключите ее как объект функции к наиболее подходящему алгоритму. Здесь работу выполняет функция

charInsCharCompSingle
, но в отличие от примера 4.21 эта функция сравнения символов переводит к верхнему регистру только первый аргумент. Это сделано потому, что немного далее в
caseInsFind
я перед использованием строки шаблона в поиске преобразую ее к верхнему регистру полностью и тем самым избегаю многократного преобразования символов строки шаблона к верхнему регистру.

После того как функция сравнения будет готова, используйте для поиска стандартные алгоритмы

transform
и
search
.
transform
используется для преобразования к верхнему регистру всего шаблона (но не целевой строки). После этого используйте для поиска места вхождения подстроки search совместно с функцией сравнения.

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

bool
, указывающий, дало ли сравнение истину или ложь.

В примере 4.22 есть одна вещь, которая выглядит странно. Вы видите, что

caseInsCompare
возвращает
const_iterator
, как в

string::const_iterator caseInsFind(const string& s,

 const string& p)

Что, если требуется изменить элемент, на который указывает возвращенный итератор? Тому есть причина. Она состоит в том, что константный итератор используется потому, что строки, которые передаются в

caseInsFind
, также передаются как
const
, и, следовательно, невозможно получить не-
const
итератор на
const
– строку. Если требуется итератор, который можно использовать для изменения строки, удалите
const
из параметров и измените объявление функции так, чтобы она возвращала
string::iterator
.

Поделиться:
Популярные книги

Хозяйка старой пасеки

Шнейдер Наталья
Фантастика:
попаданцы
фэнтези
7.50
рейтинг книги
Хозяйка старой пасеки

Измена. Не прощу

Леманн Анастасия
1. Измены
Любовные романы:
современные любовные романы
4.00
рейтинг книги
Измена. Не прощу

Черный маг императора 2

Герда Александр
2. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
6.00
рейтинг книги
Черный маг императора 2

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Не грози Дубровскому! Том III

Панарин Антон
3. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том III

Семья. Измена. Развод

Высоцкая Мария Николаевна
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Семья. Измена. Развод

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4

Сердце Дракона. Том 9

Клеванский Кирилл Сергеевич
9. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.69
рейтинг книги
Сердце Дракона. Том 9

Потомок бога

Решетов Евгений Валерьевич
1. Локки
Фантастика:
попаданцы
альтернативная история
аниме
сказочная фантастика
5.00
рейтинг книги
Потомок бога

Отмороженный 11.0

Гарцевич Евгений Александрович
11. Отмороженный
Фантастика:
боевая фантастика
рпг
попаданцы
фантастика: прочее
фэнтези
5.00
рейтинг книги
Отмороженный 11.0

Надуй щеки! Том 7

Вишневский Сергей Викторович
7. Чеболь за партой
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Надуй щеки! Том 7

Идеальный мир для Лекаря 21

Сапфир Олег
21. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 21

Антимаг его величества. Том III

Петров Максим Николаевич
3. Модификант
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Антимаг его величества. Том III

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия