4.13. Выполнение сравнения строк без учета регистра
4.13. Выполнение сравнения строк без учета регистра
Проблема
Имеются две строки и требуется узнать, не равны ли они, не учитывая регистр их символов. Например, «cat» не равно «dog», но «Cat» должна быть равна «cat», «CAT» или «caT».
Решение
Сравните строки, используя стандартный алгоритм equal (определенный в <algorithm>), и создайте свою собственную функцию сравнения, которая использует для сравнения версий с верхним регистром символов функцию toupper из <cctype> (или towupper из <cwctype> для широких символов). Пример 4.21 показывает обобщенное решение. Также он демонстрирует использование и гибкость STL. За полным объяснением обратитесь к обсуждению ниже.
Пример 4.21. Сравнение строк без учета регистра
1 #include <string>
2 #include <iostream>
3 #include <algorithm>
4 #include <cctype>
5 #include <cwctype>
6
7 using namespace std;
8
9 inline bool caseInsCharCompareN(char a, char b) {
10 return(toupper(a) == toupper(b));
11 }
12
13 inline bool caseInsCharCompareW(wchar_t a, wchar_t b) {
14 return(towupper(a) == towupper(b));
15 }
16
17 bool caseInsCompare(const string& s1, const string& s2) {
18 return((s1.size() == s2.size()) &&
19 equal(s1.begin(), s1.end(), s2.begin(), caseInsCharCompareN));
20 }
21
22 bool caseInsCompare(const wstring& s1, const wstring& s2) {
23 return((s1.size() == s2.size())
24 equal(s1.begin(), s1.end(), s2.begin(), caseInsCharCompareW));
25 }
26
27 int main() {
28 string s1 = "In the BEGINNING...";
29 string s2 = "In the beginning...";
30 wstring ws1 = L"The END";
31 wstring ws2 = L"the end";
32
33 if (caseInsCompare(s1, s2))
34 cout << "Equal! ";
35
36 if (caseInsCompare(ws1, ws2))
37 cout << "Equal! ";
38 }
Обсуждение
Критической частью сравнения строк без учета регистра является проверка равенства каждой соответствующей пары символов, так что давайте начнем обсуждение с него. Так как я в этом подходе использую стандартный алгоритм equal, но хочу использовать свой особый критерий сравнения, я должен создать отдельную функцию, выполняющую это сравнение.
Строки 9-15 примера 4.21 определяют функции, которые выполняют сравнение — caseInsCharCompareN и caseInsCharCompareW. Они для преобразования символов к верхнему регистру используют toupper и towupper, а затем сообщают, равны ли они.
После написания этих функций сравнения настает время использовать стандартный алгоритм, выполняющий применение этих функций сравнения к произвольной последовательности символов. Именно это делают функции caseInsCompare, определенные в строках 17-25 и использующие equal. Здесь сделано две перегрузки — по одной для каждого типа интересующих нас символов. Они обе делают одно и то же, но каждая использует для своего типа символов соответствующую функцию сравнения. Для этого примера я перегрузил две обычные функции, но этот же эффект может быть достигнут и с помощью шаблонов. Для пояснений обратитесь к врезке «Следует ли использовать шаблон?».
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>)) {
// они равны, делаем что-нибудь
когда требуется выполнить сравнение строк без учета регистра.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Назначение имен тегов и атрибутов зависит от регистра
Назначение имен тегов и атрибутов зависит от регистра В документах HTML имена тегов и атрибутов не зависят от регистра символов, так что, например, запись <TABLE>, <TaBle> или <table> означает один и тот же тег таблицы. Однако в XHTML это разные теги. То же самое касается имен
Функции изменения регистра
Функции изменения регистра strtolowerПроизводит преобразование символов строки в нижний регистр.Синтаксис:string strtolower(string str);Преобразует строку в нижний регистр. Возвращает результат перевода.Надо заметить, что при неправильной настройке локали функция будет выдавать, мягко
if - Выполнение или не выполнение предложений в зависимости от условий
if - Выполнение или не выполнение предложений в зависимости от условий ifПозволяет выполнить или не выполняет определенные предложения в зависимости от заданного условияСинтаксис:if (condition) { statements}Аргументы:В целом, предложение if завершается закрывающей фигурной скобкой
15.8. Программы для учета трафика
15.8. Программы для учета трафика Для мониторинга работы SQUID и вообще для учета трафика можно воспользоваться следующими программами:sqmgrlog — http://www.ineparnet.com.br/orso/index.htmlmrtg — http://www.switch.ch/misc/leinen/snmp/perl/iptraf — http://dkws.narod.ru/linux/soft/iptraf-2.4.0.tar.gzbandmin — http://www.bandmin.orgwebalizer (анализ работы
Реализация многоверсионности. Страницы учета транзакций
Реализация многоверсионности. Страницы учета транзакций Каждая транзакция в InterBase имеет свой уникальный идентификатор - transaction ID или TID (фактически это номер транзакции с момента создания базы данных или последнего restore). Каждая транзакция, запускаясь, получает свой
Глава 31 Настройка системы на особенности учета
Глава 31 Настройка системы на особенности учета Перед началом работы необходимо настроить основные параметры программы. Выберите для этого полный интерфейс конфигурации командой Сервис ? Переключение интерфейса ? Полный интерфейс.• Установка рабочей даты• Ввод
Глава 8 Ведение складского учета
Глава 8 Ведение складского учета Складской учет является одним из основных компонентов бухгалтерского учета. Какую бы финансово-хозяйственную деятельность не осуществлял субъект хозяйствования, без складского учета ему не обойтись: ведь даже предприятия, не ведущие
Глава 9 Ведение производственного учета
Глава 9 Ведение производственного учета В программе ”1С:Бухгалтерия 8” реализованы широкие функциональные возможности по ведению производственного учета. В частности вы можете вводить требования-накладные, формировать производственные отчеты, вести учет материалов,
4.14. Выполнение поиска строк без учета регистра
4.14. Выполнение поиска строк без учета регистра ПроблемаТребуется найти в строке подстроку, не учитывая разницу в регистре.РешениеИспользуйте стандартные алгоритмы transform и search, определенные в <algorithm>, а также свои собственные функции сравнения символов, аналогичные
Совет 35. Реализуйте простые сравнения строк без учета регистра символов с использованием mismatch или lexicographical_compare
Совет 35. Реализуйте простые сравнения строк без учета регистра символов с использованием mismatch или lexicographical_compare Один из вопросов, часто задаваемых новичками в STL — «Как в STL сравниваются строки без учета регистра символов?» Простота этого вопроса обманчива. Сравнения
Сравнение строк без учета регистра символов
Сравнение строк без учета регистра символов Мэтт ОстернЕсли вам когда-либо доводилось писать программы, в которых используются строки (а кому, спрашивается, не доводилось?), скорее всего, вы встречались с типичной ситуацией — две строки, различающиеся только регистром
Пример 10-27. Простой пример сравнения строк
Пример 10-27. Простой пример сравнения строк #!/bin/bash# match-string.sh: простое сравнение строкmatch_string (){ MATCH=0 NOMATCH=90 PARAMS=2 # Функция требует два входных аргумента. BAD_PARAMS=91 [ $# -eq $PARAMS ] || return $BAD_PARAMS case "$1" in "$2") return $MATCH;; * ) return $NOMATCH;; esac}a=oneb=twoc=threed=twomatch_string $a # неверное число
8.1.8. Игнорирование регистра символов
8.1.8. Игнорирование регистра символов По умолчанию команда grep чувствительна к изменению регистра символов. Чтобы провести поиск без учета регистра, воспользуйтесь опцией -i. В файле data.f обозначение месяца Sept встречается как в верхнем, так и в нижнем регистре. Поэтому для