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

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

Жанры

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
.

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

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

Шалашов Евгений Васильевич
1. Господин следователь
Детективы:
исторические детективы
5.00
рейтинг книги
Господин следователь

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Убивать чтобы жить 5

Бор Жорж
5. УЧЖ
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 5

Егерь

Астахов Евгений Евгеньевич
1. Сопряжение
Фантастика:
боевая фантастика
попаданцы
рпг
7.00
рейтинг книги
Егерь

Шесть принцев для мисс Недотроги

Суббота Светлана
3. Мисс Недотрога
Фантастика:
фэнтези
7.92
рейтинг книги
Шесть принцев для мисс Недотроги

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Последний из рода Демидовых

Ветров Борис
Фантастика:
детективная фантастика
попаданцы
аниме
5.00
рейтинг книги
Последний из рода Демидовых

Башня Ласточки

Сапковский Анджей
6. Ведьмак
Фантастика:
фэнтези
9.47
рейтинг книги
Башня Ласточки

Ротмистр Гордеев

Дашко Дмитрий Николаевич
1. Ротмистр Гордеев
Фантастика:
фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Ротмистр Гордеев

Мастер Разума II

Кронос Александр
2. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.75
рейтинг книги
Мастер Разума II

Мама для дракончика или Жена к вылуплению

Максонова Мария
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Мама для дракончика или Жена к вылуплению

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

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

Архил...?

Кожевников Павел
1. Архил...?
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Архил...?

Невеста драконьего принца

Шторм Елена
Любовные романы:
любовно-фантастические романы
5.25
рейтинг книги
Невеста драконьего принца