std::ranges:: equal
std::ranges
| Non-modifying sequence operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Modifying sequence operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Partitioning operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sorting operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Binary search operations (on sorted ranges) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Set operations (on sorted ranges) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Heap operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Minimum/maximum operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Permutation operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Fold operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Operations on uninitialized storage | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Return types | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Определено в заголовке
<algorithm>
|
||
|
Сигнатура вызова
|
||
|
template
<
std::
input_iterator
I1,
std::
sentinel_for
<
I1
>
S1,
std::
input_iterator
I2,
std::
sentinel_for
<
I2
>
S2,
|
(1) | (начиная с C++20) |
|
template
<
ranges::
input_range
R1,
ranges::
input_range
R2,
class
Pred
=
ranges::
equal_to
,
|
(2) | (начиная с C++20) |
[
first1
,
last1
)
равны проецируемым значениям диапазона
[
first2
,
last2
)
, и
false
в противном случае.
Два диапазона считаются равными, если они имеют одинаковое количество элементов и каждая пара соответствующих спроецированных элементов удовлетворяет pred . То есть, std:: invoke ( pred, std:: invoke ( proj1, * first1 ) , std:: invoke ( proj2, * first2 ) ) возвращает true для всех пар соответствующих элементов в обоих диапазонах.
Функциональные сущности, описанные на этой странице, являются алгоритмическими функциональными объектами (неформально известными как niebloids ), то есть:
- Явные списки аргументов шаблона не могут быть указаны при вызове любого из них.
- Ни один из них не видим для поиска, зависимого от аргументов .
- Когда любой из них найден обычным поиском без квалификации как имя слева от оператора вызова функции, поиск, зависимый от аргументов , блокируется.
Содержание |
Параметры
| first1, last1 | - | пара итератор-страж, определяющая первый диапазон элементов для сравнения |
| r1 | - | первый диапазон элементов для сравнения |
| first2, last2 | - | пара итератор-страж, определяющая второй диапазон элементов для сравнения |
| r2 | - | второй диапазон элементов для сравнения |
| pred | - | бинарный предикат, применяемый к проецируемым элементам |
| proj1 | - | проекция, применяемая к первому диапазону элементов |
| proj2 | - | проекция, применяемая ко второму диапазону элементов |
Возвращаемое значение
Если длина диапазона
[
first1
,
last1
)
не равна длине диапазона
[
first2
,
last2
)
, возвращает
false
.
Если элементы в двух диапазонах равны после проекции, возвращает true .
В противном случае возвращает false .
Примечания
ranges::equal
не следует использовать для сравнения диапазонов, образованных итераторами из
std::unordered_set
,
std::unordered_multiset
,
std::unordered_map
или
std::unordered_multimap
, поскольку порядок хранения элементов в этих контейнерах может различаться даже при идентичном наборе элементов.
При сравнении целых контейнеров или строковых представлений на равенство, operator == для соответствующего типа обычно предпочтительнее.
ranges::equal
не гарантирует короткое замыкание. Например, если первые парные элементы обоих диапазонов не равны, остальные элементы также могут сравниваться. Не короткозамкнутое сравнение может происходить, когда диапазоны сравниваются с помощью
std::memcmp
или специфичных для реализации векторизованных алгоритмов.
Сложность
Не более min ( last1 - first1, last2 - first2 ) применений предиката и соответствующих проекций.
Однако, если S1 и S2 оба моделируют std::sized_sentinel_for для соответствующих итераторов, и last1 - first1 ! = last2 - first2 тогда никаких применений предиката не производится (несоответствие размеров обнаруживается без просмотра каких-либо элементов).
Возможная реализация
struct equal_fn { template<std::input_iterator I1, std::sentinel_for<I1> S1, std::input_iterator I2, std::sentinel_for<I2> S2, class Pred = ranges::equal_to, class Proj1 = std::identity, class Proj2 = std::identity> requires std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2> constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const { if constexpr (std::sized_sentinel_for<S1, I1> and std::sized_sentinel_for<S2, I2>) if (std::ranges::distance(first1, last1) != std::ranges::distance(first2, last2)) return false; for (; first1 != last1; ++first1, (void)++first2) if (!std::invoke(pred, std::invoke(proj1, *first1), std::invoke(proj2, *first2))) return false; return true; } template<ranges::input_range R1, ranges::input_range R2, class Pred = ranges::equal_to, class Proj1 = std::identity, class Proj2 = std::identity> requires std::indirectly_comparable<ranges::iterator_t<R1>, ranges::iterator_t<R2>, Pred, Proj1, Proj2> constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const { return (*this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), std::ref(pred), std::ref(proj1), std::ref(proj2)); } }; inline constexpr equal_fn equal; |
Пример
Следующий код использует ranges::equal для проверки, является ли строка палиндромом.
#include <algorithm> #include <iomanip> #include <iostream> #include <ranges> #include <string_view> constexpr bool is_palindrome(const std::string_view s) { namespace views = std::views; auto forward = s | views::take(s.size() / 2); auto backward = s | views::reverse | views::take(s.size() / 2); return std::ranges::equal(forward, backward); } void test(const std::string_view s) { std::cout << std::quoted(s) << " is " << (is_palindrome(s) ? "" : "not ") << "a palindrome\n"; } int main() { test("radar"); test("hello"); static_assert(is_palindrome("ABBA") and not is_palindrome("AC/DC")); }
Вывод:
"radar" is a palindrome "hello" is not a palindrome
Смотрите также
|
(C++20)
(C++20)
(C++20)
|
находит первый элемент, удовлетворяющий определённым критериям
(функциональный объект алгоритма) |
|
(C++20)
|
возвращает
true
если один диапазон лексикографически меньше другого
(функциональный объект алгоритма) |
|
(C++20)
|
находит первую позицию, в которой два диапазона различаются
(функциональный объект алгоритма) |
|
(C++20)
|
ищет первое вхождение диапазона элементов
(функциональный объект алгоритма) |
|
(C++20)
|
возвращает диапазон элементов, соответствующих определённому ключу
(функциональный объект алгоритма) |
|
функциональный объект, реализующий
x
==
y
(шаблон класса) |
|
|
определяет, идентичны ли два набора элементов
(шаблон функции) |