std::ranges:: is_permutation
|
Definiert im Header
<algorithm>
|
||
|
Aufrufsignatur
|
||
|
template
<
std::
forward_iterator
I1,
std::
sentinel_for
<
I1
>
S1,
std::
forward_iterator
I2,
std::
sentinel_for
<
I2
>
S2,
|
(1) | (seit C++20) |
|
template
<
ranges::
forward_range
R1,
ranges::
forward_range
R2,
class
Proj1
=
std::
identity
,
class
Proj2
=
std::
identity
,
|
(2) | (seit C++20) |
[
first1
,
last1
)
existiert, die den Bereich
gleich
zu
[
first2
,
last2
)
macht (nach Anwendung der entsprechenden Projektionen
Proj1
,
Proj2
und unter Verwendung des binären Prädikats
Pred
als Komparator). Andernfalls wird
false
zurückgegeben.
Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithm Function Objects (informell bekannt als Niebloids ), das heißt:
- Explizite Template-Argumentlisten können beim Aufruf keiner von ihnen angegeben werden.
- Keiner von ihnen ist sichtbar für argument-dependent lookup .
- Wenn einer von ihnen durch normal unqualified lookup als Name links vom Funktionsaufrufoperator gefunden wird, wird argument-dependent lookup unterdrückt.
Inhaltsverzeichnis |
Parameter
| first1, last1 | - | das Iterator-Sentinel-Paar, das den ersten Bereich von Elementen definiert |
| first2, last2 | - | das Iterator-Sentinel-Paar, das den zweiten Bereich von Elementen definiert |
| r1 | - |
der erste
range
der Elemente
|
| r2 | - |
der zweite
range
der Elemente
|
| pred | - | Prädikat, das auf die projizierten Elemente angewendet wird |
| proj1 | - | Projektion, die auf die Elemente im ersten Bereich angewendet wird |
| proj2 | - | Projektion, die auf die Elemente im zweiten Bereich angewendet wird |
Rückgabewert
true
falls der Bereich
[
first1
,
last1
)
eine Permutation des Bereichs
[
first2
,
last2
)
ist.
Komplexität
Höchstens O(N 2 ) Anwendungen des Prädikats und jeder Projektion, oder genau N falls die Sequenzen bereits gleich sind, wobei N ist ranges:: distance ( first1, last1 ) . Allerdings falls ranges:: distance ( first1, last1 ) ! = ranges:: distance ( first2, last2 ) , werden keine Anwendungen des Prädikats und der Projektionen durchgeführt.
Hinweise
Die Permutation -Relation ist eine Äquivalenzrelation .
Die
ranges::is_permutation
kann im Testing verwendet werden, z.B. um die Korrektheit von umordnenden Algorithmen wie Sortieren, Mischen, Partitionieren zu überprüfen. Wenn
p
eine ursprüngliche Sequenz ist und
q
eine "mutierte" Sequenz, dann bedeutet
ranges
::
is_permutation
(
p, q
)
==
true
, dass
q
aus "denselben" Elementen (möglicherweise permutiert) besteht wie
p
.
Mögliche Implementierung
struct is_permutation_fn { template<std::forward_iterator I1, std::sentinel_for<I1> S1, std::forward_iterator I2, std::sentinel_for<I2> S2, class Proj1 = std::identity, class Proj2 = std::identity, std::indirect_equivalence_relation<std::projected<I1, Proj1>, std::projected<I2, Proj2>> Pred = ranges::equal_to> constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const { // gemeinsamen Präfix überspringen auto ret = std::ranges::mismatch(first1, last1, first2, last2, std::ref(pred), std::ref(proj1), std::ref(proj2)); first1 = ret.in1, first2 = ret.in2; // über den Rest iterieren, zählen wie oft jedes Element vorkommt // aus [first1, last1) erscheint in [first2, last2) for (auto i {first1}; i != last1; ++i) { const auto i_proj {std::invoke(proj1, *i)}; auto i_cmp = [&]<typename T>(T&& t) { return std::invoke(pred, i_proj, std::forward<T>(t)); }; if (i != ranges::find_if(first1, i, i_cmp, proj1)) continue; // dieser *i wurde geprüft if (const auto m {ranges::count_if(first2, last2, i_cmp, proj2)}; m == 0 or m != ranges::count_if(i, last1, i_cmp, proj1)) return false; } return true; } template<ranges::forward_range R1, ranges::forward_range R2, class Proj1 = std::identity, class Proj2 = std::identity, std::indirect_equivalence_relation< std::projected<ranges::iterator_t<R1>, Proj1>, std::projected<ranges::iterator_t<R2>, Proj2>> Pred = ranges::equal_to> 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::move(pred), std::move(proj1), std::move(proj2)); } }; inline constexpr is_permutation_fn is_permutation {}; |
Beispiel
#include <algorithm> #include <array> #include <cmath> #include <iostream> #include <ranges> auto& operator<<(auto& os, std::ranges::forward_range auto const& v) { os << "{ "; for (const auto& e : v) os << e << ' '; return os << "}"; } int main() { static constexpr auto r1 = {1, 2, 3, 4, 5}; static constexpr auto r2 = {3, 5, 4, 1, 2}; static constexpr auto r3 = {3, 5, 4, 1, 1}; static_assert( std::ranges::is_permutation(r1, r1) && std::ranges::is_permutation(r1, r2) && std::ranges::is_permutation(r2, r1) && std::ranges::is_permutation(r1.begin(), r1.end(), r2.begin(), r2.end())); std::cout << std::boolalpha << "is_permutation(" << r1 << ", " << r2 << "): " << std::ranges::is_permutation(r1, r2) << '\n' << "is_permutation(" << r1 << ", " << r3 << "): " << std::ranges::is_permutation(r1, r3) << '\n' << "is_permutation with custom predicate and projections: " << std::ranges::is_permutation( std::array {-14, -11, -13, -15, -12}, // 1st range std::array {'F', 'E', 'C', 'B', 'D'}, // 2nd range [](int x, int y) { return abs(x) == abs(y); }, // predicate [](int x) { return x + 10; }, // projection for 1st range [](char y) { return int(y - 'A'); }) // projection for 2nd range << '\n'; }
Ausgabe:
is_permutation({ 1 2 3 4 5 }, { 3 5 4 1 2 }): true
is_permutation({ 1 2 3 4 5 }, { 3 5 4 1 1 }): false
is_permutation with custom predicate and projections: true
Siehe auch
|
(C++20)
|
erzeugt die nächstgrößere lexikografische Permutation eines Elementbereichs
(Algorithmus-Funktionsobjekt) |
|
(C++20)
|
erzeugt die nächstkleinere lexikografische Permutation eines Elementbereichs
(Algorithmus-Funktionsobjekt) |
|
(C++11)
|
bestimmt, ob eine Sequenz eine Permutation einer anderen Sequenz ist
(Funktionstemplate) |
|
erzeugt die nächstgrößere lexikografische Permutation eines Elementbereichs
(Funktionstemplate) |
|
|
erzeugt die nächstkleinere lexikografische Permutation eines Elementbereichs
(Funktionstemplate) |
|
|
(C++20)
|
spezifiziert, dass eine
relation
eine Äquivalenzrelation definiert
(Konzept) |