最終更新日時(UTC):
が更新

履歴 編集

function template
<algorithm>

std::partition_point(C++11)

namespace std {
  template <class ForwardIterator, class Predicate>
  ForwardIterator
    partition_point(ForwardIterator first,
                    ForwardIterator last,
                    Predicate pred);       // C++11

  template <class ForwardIterator, class Predicate>
  constexpr ForwardIterator
    partition_point(ForwardIterator first,
                    ForwardIterator last,
                    Predicate pred);       // C++20
}

概要

イテレータ範囲[first, last)から条件によって区分化されている位置を得る。

テンプレートパラメータ制約

  • ForwardIterator の value type は Predicate の引数型へ変換可能であること

事前条件

  • イテレータ範囲[first,last)pred によって区分化されていなければならない。つまり、pred を満たす全ての要素が、pred を満たさない全ての要素より前に出現してなければならない

戻り値

all_of(first, mid, pred)none_of(mid, last, pred)true であるようなイテレータ mid を返す。

計算量

pred が O(log(last - first)) 回適用される。

#include <iostream>
#include <vector>
#include <algorithm>

void print(const char* name, const std::vector<int>& v)
{
  std::cout << name << " : ";
  std::for_each(v.begin(), v.end(), [](int x) {
    std::cout << x << ",";
  });
  std::cout << std::endl;
}

bool is_even(int x) { return x % 2 == 0; }

int main()
{
  std::vector<int> v = {1, 2, 3, 4, 5};

  std::partition(v.begin(), v.end(), is_even);

  // 偶数グループと奇数グループに分かれた位置を得る
  decltype(v)::iterator it = std::partition_point(v.begin(), v.end(), is_even);

  print("v", v);
  std::cout << *it << std::endl;
}

出力

v : 4,2,3,1,5,
3

実装例

template<class ForwardIterator, class Predicate>
ForwardIterator
partition_point(ForwardIterator first, ForwardIterator last, Predicate pred)
{
  for (auto len = std::distance(first, last); len != 0; ) {
    auto half = len / 2;
    auto mid = std::next(first, half);
    if (pred(*mid)) {
      len -= half + 1;
      first = std::next(mid);
    } else {
      len = half;
    }
  }
  return first;
}

バージョン

言語

  • C++11

処理系

参照