名前空間
変種
操作

std::minmax_element

提供: cppreference.com
< cpp‎ | algorithm
2019年1月31日 (木) 14:11時点におけるMilkpot (トーク | 投稿記録)による版

 
 
アルゴリズムライブラリ
制約付きアルゴリズムと範囲に対するアルゴリズム (C++20)
コンセプトとユーティリティ: std::sortable, std::projected, ...
制約付きアルゴリズム: std::ranges::copy, std::ranges::sort, ...
実行ポリシー (C++17)
非変更シーケンス操作
(C++11)(C++11)(C++11)
(C++17)
変更シーケンス操作
未初期化記憶域の操作
分割操作
ソート操作
(C++11)
二分探索操作
集合操作 (ソート済み範囲用)
ヒープ操作
(C++11)
最小/最大演算
(C++11)
minmax_element
(C++11)
(C++17)

順列
数値演算
C のライブラリ
 
ヘッダ <algorithm> で定義
(1)
template< class ForwardIt >

std::pair<ForwardIt,ForwardIt>

    minmax_element( ForwardIt first, ForwardIt last );
(C++11以上)
(C++17未満)
template< class ForwardIt >

constexpr std::pair<ForwardIt,ForwardIt>

    minmax_element( ForwardIt first, ForwardIt last );
(C++17以上)
template< class ExecutionPolicy, class ForwardIt >

std::pair<ForwardIt,ForwardIt>

    minmax_element( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last );
(2) (C++17以上)
(3)
template< class ForwardIt, class Compare >

std::pair<ForwardIt,ForwardIt>

    minmax_element( ForwardIt first, ForwardIt last, Compare comp );
(C++11以上)
(C++17未満)
template< class ForwardIt, class Compare >

constexpr std::pair<ForwardIt,ForwardIt>

    minmax_element( ForwardIt first, ForwardIt last, Compare comp );
(C++17以上)
template< class ExecutionPolicy, class ForwardIt, class Compare >

std::pair<ForwardIt,ForwardIt>

    minmax_element( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, Compare comp );
(4) (C++17以上)

範囲 [first, last) 内の最も小さな要素と最も大きな要素を探します。

1) 要素は operator< を用いて比較されます。
3) 要素は指定された二項比較関数 comp を用いて比較されます。
2,4) (1,3) と同じですが、 policy に従って実行されます。 これらのオーバーロードは、 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> が true でなければ、オーバーロード解決に参加しません。

目次

引数

first, last - 調べる範囲を定義する前方イテレータ
policy - 使用する実行ポリシー。 詳細は実行ポリシーを参照してください
cmp - *a*b より小さい場合に true を返す、比較関数オブジェクト (Compare の要件を満たすオブジェクト)。

比較関数のシグネチャは以下と同等であるべきです。

 bool cmp(const Type1 &a, const Type2 &b);

シグネチャが const & を持つ必要はありませんが、関数は渡されたオブジェクトを変更してはならず、値カテゴリに関わらず Type1 および Type2 型 (およびそれらの const 修飾された型) のすべての値を受理できなければなりません (そのため Type1 & は許されません。 また Type1 に対してムーブがコピーと同等でなければ Type1 も許されません (C++11以上))。
Type1 および Type2 は、どちらも ForwardIt 型のオブジェクトの逆参照から暗黙に変換可能なものでなければなりません。 ​

型の要件
-
ForwardItLegacyForwardIterator の要件を満たさなければなりません。

戻り値

第1要素として最も小さな要素を指すイテレータを持ち第2要素として最も大きな要素を指すイテレータを持つペア。 範囲が空の場合は std::make_pair(first, first) を返します。 最も小さな同等な要素が複数ある場合は、最初のそのような要素を指すイテレータが返されます。 最も大きな同等な要素が複数ある場合は、最後のそのような要素を指すイテレータが返されます。

計算量

多くとも max(floor((3/2)*(N−1)), 0) 回の述語の適用、ただし N = std::distance(first, last) です。

例外

テンプレート引数 ExecutionPolicy を持つオーバーロードは以下のようにエラーを報告します。

  • アルゴリズムの一部として呼び出された関数の実行が例外を投げ、 ExecutionPolicy標準のポリシーのいずれかの場合は、 std::terminate が呼ばれます。 それ以外のあらゆる ExecutionPolicy については、動作は処理系定義です。
  • アルゴリズムがメモリの確保に失敗した場合は、 std::bad_alloc が投げられます。

ノート

このアルゴリズムは std::make_pair(std::min_element(), std::max_element()) と異なります。 効率性だけでなく、このアルゴリズムは最も大きな最後の要素を探しますが、 std::max_element は最も大きな最初の要素を探します。

実装例

1つめのバージョン
template<class ForwardIt>
std::pair<ForwardIt, ForwardIt> 
    minmax_element(ForwardIt first, ForwardIt last)
{
    return std::minmax_element(first, last, std::less<>());
}
2つめのバージョン
template <class ForwardIt, class Compare>
std::pair<ForwardIt, ForwardIt> minmax_element(ForwardIt it, ForwardIt last,
                                               Compare comp) {
	const auto it_comp = [&comp](const auto& lhs, const auto& rhs) {
		return comp(*lhs, *rhs);
	};
 
	auto min = it;
	auto max = it;
 
	if (it == last or ++it == last) {
		return {min, max};
	}
 
	if (it_comp(it, min)) {
		min = it++;
	} else {
		max = it++;
	}
 
        // 「it」はループの繰り返しごとに2回インクリメントされ、
        // 述語の呼び出しは繰り返しごとに3回あることに注意してください。
        // これは要素ごとにおよそ3/2回の呼び出しがあることを意味します。
	while (it != last) {
		const auto i0 = it++; // 1回目の前進。
		if (it == last) {
			if (it_comp(i0, min)) {
				min = i0;
			} else {
				max = std::max(i0, max, it_comp);
			}
			break;
		}
		const auto i1 = it++; // 2回目の前進。
		const auto [min_it, max_it] = std::minmax(i0, i1, it_comp);
		min = std::min(min, min_it, it_comp);
		max = std::max(max_it, max, it_comp);
	}
	return {min, max};
}
}

#include <algorithm>
#include <iostream>
#include <vector>
 
int main() {
    const auto v = { 3, 9, 1, 4, 2, 5, 9 };
    const auto [min, max] = std::minmax_element(begin(v), end(v));
 
    std::cout << "min = " << *min << ", max = " << *max << '\n';
}

出力:

min = 1, max = 9

関連項目

指定範囲の最も小さな要素を返します
(関数テンプレート) [edit]
指定範囲の最も大きな要素を返します
(関数テンプレート) [edit]