std::lexicographical_compare
| ヘッダー <algorithm> で定義 |
||
template< class InputIt1, class InputIt2 > bool lexicographical_compare( InputIt1 first1, InputIt1 last1, |
(1) | (C++20 以降 constexpr) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 > |
(2) | (C++17以降) |
template< class InputIt1, class InputIt2, class Compare > bool lexicographical_compare( InputIt1 first1, InputIt1 last1, |
(3) | (C++20 以降 constexpr) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class Compare > |
(4) | (C++17以降) |
最初の範囲 [first1, last1) が、2番目の範囲 [first2, last2) よりも辞書順で小さいかどうかをチェックします。
|
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> が true である。 |
(C++20まで) |
|
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> は true です。 |
(C++20以降) |
辞書順比較は、以下の特性を持つ操作です。
- 2つの範囲は要素ごとに比較されます。
- 最初に一致しない要素が、どちらの範囲が他方よりも辞書順で 小さい または 大きい かを定義します。
- 一方の範囲がもう一方の範囲のプレフィックスである場合、短い方の範囲が辞書順で 小さい とみなされます。
- 2つの範囲の要素が等しく、長さも同じ場合、その範囲は辞書順で 等しい とみなされます。
- 空の範囲は、任意の非空の範囲よりも辞書順で 小さい とみなされます。
- 2つの空の範囲は、辞書順で 等しい とみなされます。
目次 |
[edit] パラメータ
| first1, last1 | - | 調べる最初の要素の 範囲 を定義するイテレータのペア |
| first2, last2 | - | 調べる2番目の要素の 範囲 を定義するイテレータのペア |
| policy | - | 使用する 実行ポリシー |
| comp | - | 比較関数オブジェクト(すなわち、Compareの要件を満たすオブジェクト)。最初の引数が2番目の引数より小さい場合にtrueを返す。 比較関数のシグネチャは、以下と同等でなければならない。 bool cmp(const Type1& a, const Type2& b); シグネチャにconst&は必須ではないが、関数は渡されたオブジェクトを変更してはならず、値カテゴリに関係なく、 |
| 型要件 | ||
-InputIt1, InputIt2 は LegacyInputIterator の要件を満たす必要がある。 | ||
-ForwardIt1, ForwardIt2 は LegacyForwardIterator の要件を満たさなければなりません。 | ||
-CompareはCompareの要件を満たす必要がある。 | ||
[edit] 戻り値
最初の範囲が2番目の範囲より辞書順で小さい場合は true、それ以外の場合は false。
[edit] 計算量
std::distance(first1, last1) を N1 とし、std::distance(first2, last2) を N2 とする。
[edit] 例外
ExecutionPolicy というテンプレートパラメータを持つオーバーロードは、次のようにエラーを報告します。
- アルゴリズムの一部として呼び出された関数の実行が例外をスローし、
ExecutionPolicyが 標準ポリシー のいずれかである場合、std::terminate が呼び出されます。その他のExecutionPolicyの場合、動作は実装定義です。 - アルゴリズムがメモリの割り当てに失敗した場合、std::bad_alloc がスローされます。
[edit] 実装例
| lexicographical_compare (1) |
|---|
template<class InputIt1, class InputIt2> bool lexicographical_compare(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) { for (; (first1 != last1) && (first2 != last2); ++first1, (void) ++first2) { if (*first1 < *first2) return true; if (*first2 < *first1) return false; } return (first1 == last1) && (first2 != last2); } |
| lexicographical_compare (3) |
template<class InputIt1, class InputIt2, class Compare> bool lexicographical_compare(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Compare comp) { for (; (first1 != last1) && (first2 != last2); ++first1, (void) ++first2) { if (comp(*first1, *first2)) return true; if (comp(*first2, *first1)) return false; } return (first1 == last1) && (first2 != last2); } |
[edit] 例
#include <algorithm> #include <iostream> #include <random> #include <vector> void print(const std::vector<char>& v, auto suffix) { for (char c : v) std::cout << c << ' '; std::cout << suffix; } int main() { std::vector<char> v1{'a', 'b', 'c', 'd'}; std::vector<char> v2{'a', 'b', 'c', 'd'}; for (std::mt19937 g{std::random_device{}()}; !std::lexicographical_compare(v1.begin(), v1.end(), v2.begin(), v2.end());) { print(v1, ">= "); print(v2, '\n'); std::shuffle(v1.begin(), v1.end(), g); std::shuffle(v2.begin(), v2.end(), g); } print(v1, "< "); print(v2, '\n'); }
実行結果の例
a b c d >= a b c d d a b c >= c b d a b d a c >= a d c b a c d b < c d a b
[edit] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 142 | C++98 | 最大 min(N1,N2) 回の比較が許可されていましたが、それは 不可能でした(等価性は2回の比較で決定されます)。 |
上限を2倍しました。 |
| LWG 1205 | C++98 | 空の範囲を含む辞書順比較の結果が不明確でした。 | 明確化された |
[edit] 関連項目
| 2つの要素の集合が同じかどうかを判断する (関数テンプレート) | |
| 三方比較を用いて2つの範囲を比較する (関数テンプレート) | |
| ある範囲が別の範囲より辞書順で小さい場合に true を返す (アルゴリズム関数オブジェクト) |