Использование функции set::find STL в Visual C++
В этой статье показано, как использовать функцию Стандартной set::find библиотеки шаблонов (STL) в Visual C++.
Исходная версия продукта: Visual C++
Исходный номер базы знаний: 158576
Обязательный заголовок
Прототип
template class set < public: // Function 1: const_iterator find(const _K& _Kv) const; >
Имена классов и параметров в прототипе могут не соответствовать версии в файле заголовка. Некоторые из них были изменены для повышения удобочитаемости.
Описание функции set::find
Функция find используется для поиска элемента в управляемой последовательности. Он возвращает итератор первому элементу управляемой последовательности, ключ сортировки которого соответствует его параметру. Если такого элемента не существует, возвращенный итератор равен end() .
Пример кода
В Visual C++ .NET и Visual C++ параметр /EHsc задается по умолчанию и эквивалентен /GX.
////////////////////////////////////////////////////////////////////// // Compile options needed: -GX // SetFind.cpp: // Illustrates how to use the find function to get an iterator // that points to the first element in the controlled sequence // that has a particular sort key. // Functions: // find Returns an iterator that points to the first element // in the controlled sequence that has the same sort key // as the value passed to the find function. If no such // element exists, the iterator equals end(). // Copyright (c) 1996 Microsoft Corporation. All rights reserved. ////////////////////////////////////////////////////////////////////// #pragma warning(disable:4786) #include #include #if _MSC_VER > 1020 // if VC++ version is > 4.2 using namespace std; // std c++ libs implemented in std #endif typedef set,allocator > SET_INT; void truefalse(int x) < cout void main() < SET_INT s1; cout
Выходные данные программы
s1.insert(5) s1.insert(8) s1.insert(12) it=find(8) it!=s1.end() returned True it=find(6) it!=s1.end() returned False
Find c что это
Функция std::find() ищет на определенном диапазоне элементов определенное значение. Для сравнения значений применяется операция сравнения ==. Рассмотрим одну из версий функции:
std::find(start_iterator, end_iterator, value)
Для установки диапазона в функцию передаются итератор на начало и конец диапазона и значение, которое надо найти. Результат функции - итератор на найденное значение. Если же значение не найдено, то возвращаемый итератор указывает на конец диапазона. Например, попробуем найти в векторе чисел некоторые числа
#include #include #include void findValue (const std::vector& data, int value) < auto result< std::find(begin(data), end(data), value) >; if (result == end(data)) std::cout int main() < std::vectornumbers < 1, 2, 3, 4, 5, 6, 7, 8>; findValue(numbers, 4); // Value found at position 3 findValue(numbers, 12); // Value not found >
В данном случае поиск вынесен в отдельную функцию - findValue. В ней ищем в векторе чисел некоторое число. В качестве начала и конца диапазона для поиска в функцию std::find() передаются итераторы на начало и конец вектор:
auto result< std::find(begin(data), end(data), value) >;
Если число не найдено, то полученный итератор равен итератору на конец вектора:
if (result == end(data))
Если же число найдено, то вычитая из полученного итератора итератор на начало вектора, мы можем получить индекс числа в векторе:
std::coutПоиск по условию
Ряд дополнительных функций возвращают итератор на значение в зависимости от некоторого условия. Функция std::find_if() возвращает итератор на первый элемент диапазона, который удовлетворяет некоторому условию. А функция std::find_if_not() , наоброт, возвращает итератор на первый элемент диапазона, который НЕ удовлетворяет некоторому условиЮ. Посмотрим на примере функции std::find_if() :
#include #include #include // если число четное bool is_even(int n) < return n % 2 == 0;>// если число положительное bool is_positive(int n) < return n >0;> // если число больше 10 bool is_greater10(int n) < return n >10;> template void findValue (const std::vector& data, bool(*condition)(T)) < auto result< std::find_if(begin(data), end(data), condition) >; if (result == end(data)) std::cout int main() < std::vectornumbers < -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5>; findValue(numbers, is_even); // Value found at position 1 findValue(numbers, is_positive); // Value found at position 6 findValue(numbers, is_greater10); // Value not found >Функция std::find_if() также получает итераторы на начало и конец дипазона для поиска, а третий параметр представляет условие, которому должны удовлетворять значения:
std::find_if(begin(data), end(data), condition)Условие представляет функцию, которая принимает некоторое значение произвольного типа и возвращает значение типа bool - true , если значение соответствует условию, и false , если не соответствует. Фактически условие можно описать указателем на функцию bool(*condition)(T) , где T- произвольный тип.
Для теста здесь определены три функции, которые представляют условия: is_even() (проверяет, является ли число четным), is_positive() (если число положительное) и is_greater10() (если число больше 10).
Функция std::find_if() возвращает итератор на первое найденное значение, которое удовлетворяет условию. Если таких значений не найдено, то итератор указывает на конец диапазона.
Принцип работы std::find_if_not() будет аналогичен.
Почему std::find возвращает указатель?
зачем использовать именно указатель p, а не просто переменную p. Мы же не собираемся никак менять элемент массива. Нам просто нужно поискать его в массиве и все. Почему нельзя это сделать без указателя? Заранее спасибо!
Отслеживать
123k 24 24 золотых знака 126 126 серебряных знаков 303 303 бронзовых знака
задан 10 янв 2021 в 23:15
341 5 5 серебряных знаков 15 15 бронзовых знаковstd::find ищет в диапазоне [first, last) ( last не включается) возвращает last , если ничего не найдено
10 янв 2021 в 23:51
3 ответа 3
Сортировка: Сброс на вариант по умолчанию
- То, что ты в конкретном примере чего-то делать не собираешься, не означает, что это не нужно. То, что возвращает find может использоваться и для изменения значения, и даже для изменения контейнера - например, обрезать вектор после или перед найденным элементом. А ещё можно что-то делать с соседними элементами.
- Даже если представить, что по некоторой причине завелись две функции - одна ищет указатель (а вообще-то она шаблонная и указатель - это твой вариант, а там может быть любой итератор), а другая - значение, то со значением возникает проблема. Надо как-то уметь отличать ситуацию, когда значение найдено от ситуации, когда оно не найдено. Поскольку мы можем искать любое значение, то надо каким-то образом обеспечить возможность возврата на одно значение больше, чем вмещает используемый тип. Например, при считывании файла нормальные символы вмещаются в char, а getc возвращает int чтобы суметь предоставить EOF вне допустимого диапазона char. Очевидно, что для произвольного типа это сделать затруднительно и чуть ли не единственным вариантом станет возвращать структуру с найденным значением и флагом. Стоп. Структуру с найденным значением? Но не копировать же в неё значение? Тогда структуру с указателем и флагом? А нафига нам теперь флаг, если сам указатель можно использовать для того, чтобы показать, что ничего не найдено?
- Ну и конкретно про find. Ты ему передаёшь число 30. Если представить, что он вернёт тебе те же самые 30, то нафига тебе это надо? Функция, которая принимает пару итераторов и возвращает свой третий аргумент?
- А в твоём коде можно заменить find на count, тогда число можно сразу использовать в качестве флага. Впрочем, формально производительность этого кода будет хуже, если только компилятор не догадается что-нибудь заинлайнить и выкинуть лишнее, так что я бы оставил find.
Отслеживать
ответ дан 11 янв 2021 в 0:09
123k 24 24 золотых знака 126 126 серебряных знаков 303 303 бронзовых знакаЕсть еще std::any_of , который вернет истину, если хотя бы для одного элемента предикат вернет true .
11 янв 2021 в 6:53
@Croessmah, но ему нужен предикат, то в данном случае менее удобно.
11 янв 2021 в 7:15Здравствуйте! А почему после просьбы "найдите в толпе человека с красной шапкой" вы пальцем указываете на этого человека, а не отвечаете "человек с красной шапочкой".
Принимает любой тип, который ведет себя как указатель ( итератор для чтения ) и возвращает его(в данном случаи указатель). Это обобщенный алгоритм, и для него логична команда "отсюда до сюда найти это". Алгоритм находит и "говорит", что нашел его в этом месте (возвращает итератор, указывающий на это место) или не нашел(возвращает итератор, указывающий за конец последовательности.
Иначе и не построишь логику такого рода команды и выполнения, потому что, если алгоритм каким то образом просто сообщит о том, что нашел, то останется вопрос: "а в каком месте?". Еще хуже, если он вернет значение(а какое значение вернуть, чтобы вы знали, что он не нашел? А если нашел, зачем вам нужно это значение, если оно и так у вас есть?). А зная место, все вопросы исчерпаны.
поиск
Выполняет поиск строки текста в файле или файлах и отображает строки текста, содержащие указанную строку.
Синтаксис
find [/v] [/c] [/n] [/i] [/off[line]] [[:][][. ]]Параметры
| Параметр | Описание |
|---|---|
| /v | Отображает все строки, которые не содержат указанные . |
| /c | Подсчитывает строки, содержащие указанные и отображающие итог. |
| /N | Предшествует каждой строке с номером строки файла. |
| /i | Указывает, что поиск не учитывает регистр. |
| [/off[line]] | Не пропускает файлы, имеющие автономный набор атрибутов. |
| Обязательно. Указывает группу символов (заключенную в кавычки), которую требуется найти. | |
| [:][] | Указывает расположение и имя файла, в котором выполняется поиск указанной строки. |
| /? | Отображение справки в командной строке. |
Коды выхода
| Код выхода | Description |
|---|---|
| 0 | Найдена поисковая строка |
| 1 | Поиск не найденной строки |
| 2 | Не найден или недопустимый переключатель командной строки для поиска |
Замечания
- Если вы не используете /i, эта команда ищет именно то, что вы указываете для строки. Например, эта команда обрабатывает символы a и A по-разному. Если вы используете /i, однако поиск становится нечувствительным к регистру, и он обрабатывается a и A как тот же символ.
- Если строка, которую вы хотите найти, содержит кавычки, необходимо использовать двойные кавычки для каждой кавычки, содержащейся в строке (например, """Эта строка содержит кавычки"".
- Если не указать имя файла, эта команда выступает в качестве фильтра, принимая входные данные из стандартного источника ввода (обычно клавиатура, канал (|) или перенаправленный файл), а затем отображает все строки, содержащие строку.
- Чтобы выйти из консоли, используйте CTRL-X или CTRL-z .
- Параметры и параметры командной строки можно вводить для команды поиска в любом порядке.
- Вы не можете использовать дикие карта (* и ?) в строке поиска. Для поиска строки с дикими карта и шаблонами регулярных выражений можно использовать команду FINDSTR.
- При использовании /c и /v в одной командной строке эта команда отображает количество строк, которые не содержат указанную строку. Если указать /c и /n в той же командной строке, найдите игнорировать /n.
- Эта команда не распознает возврат каретки. При использовании этой команды для поиска текста в файле, включающего возврат каретки, необходимо ограничить строку поиска текстом, который можно найти между возвратом каретки (т. е. строка, которая, скорее всего, не будет прервана возвратом каретки). Например, эта команда не сообщает о совпадении со строковым налоговым файлом, если возврат каретки происходит между словами налогом и файлом.
- Команда принимает дикие карта ые имена файлов. При поиске в файле (или файлах) он выводит файл обработанного файла, предшествовающего десяти дефисам.
- Команда find не может считывать альтернативные потоки данных. Для поиска в альтернативных потоках данных используется findstr, более или для команд /f .
Примеры
Чтобы отобразить все строки из pencil.md, которые содержат заточитель карандаша строки, введите:
find "pencil sharpener" pencil.md
Чтобы найти текст, "Ученые назвали свой документ только для обсуждения. Это не окончательный доклад". (включая кавычки) в файле report.txt, введите:
find """The scientists labeled their paper for discussion only. It is not a final report.""" < report.txt
Для поиска набора файлов можно использовать дикие карта. Чтобы выполнить поиск в текущем каталоге для файлов с расширением .bat и содержащих строку PROMPT , игнорирующую регистр, введите:
find /i "PROMPT" *.bat
Чтобы найти имена файлов в каталоге с строковым ЦП, используйте канал (|), чтобы направить выходные данные команды dir в команду поиска следующим образом:
dir c:\temp /s /b | find "CPU"
Найдите все выполняемые процессы, которые не содержат агент:
tasklist | find /v /i "agent"
Проверьте, запущена ли служба:
sc query Winmgmt | find "RUNNING" >nul 2>&1 && (echo service is started) || (echo service is stopped)
Дополнительные ссылки
- Условные обозначения синтаксиса команд командной строки
- Команда findstr