std::ranges::rotate
| ヘッダで定義 <algorithm>
|
||
| 呼び出しシグネチャ |
||
template< std::permutable I, std::sentinel_for<I> S >
constexpr ranges::subrange<I>
rotate( I first, I middle, S last );
|
(1) | (C++20から) |
template< ranges::forward_range R >
requires std::permutable<ranges::iterator_t<R>>
constexpr ranges::borrowed_subrange_t<R>
rotate( R&& r, ranges::iterator_t<R> middle );
|
(2) | (C++20から) |
ranges::rotate 範囲内の要素を交換し、[first, last) そのようにして要素 *middle が新しい範囲の最初の要素になり、*(middle - 1) が最後の要素になります。[first, last) が有効な範囲でないか、middle が [first, last) に含まれていない場合。r を範囲として使用し、ranges::begin(r) として first と ranges::end(r) として lastこのページで説明されている関数のようなエンティティは、アルゴリズム関数オブジェクト (非公式に niebloids として知られています)。すなわち: 明示的なテンプレート引数リストは、それらのいずれかを呼び出すときに指定できません。
- それらは
- 引数依存の名前探索 に表示されません。それらのいずれかが
- 通常の非修飾名前探索 によって関数呼び出し演算子の左側の名前として見つかった場合、引数依存の名前探索 は抑制されます。
パラメータ
| first, last | - | 回転させる要素の 範囲 を定義するイテレータ-番兵ペア |
| r | - | 回転させる要素の範囲 |
| middle | - | 回転後の範囲の先頭に現れるべき要素を指すイテレータ |
戻り値
{
new_first, last
}
、ここで
new_first
は
ranges::
next
(
first,
ranges::
distance
(
middle, last
)
)
と等価であり、
first
が指していた要素の新しい位置を示します。
計算量
Linear at worst: ranges:: distance ( first, last ) 回のスワップ。
注記
ranges::rotate
は、
I
が
bidirectional_iterator
または(さらに良い)
random_access_iterator
をモデル化する場合、一般的な実装ではより高い効率性を持ちます。
実装(例:
MSVC STL
)は、イテレータ型が
contiguous_iterator
をモデルし、その値型の交換が非自明な特殊メンバ関数も
ADL
で発見された
swap
も呼び出さない場合、ベクトル化を有効化することがあります。
実装例
実装については libstdc++ および MSVC STL も参照してください。
struct rotate_fn
{
template<std::permutable I, std::sentinel_for<I> S>
constexpr ranges::subrange<I>
operator()(I first, I middle, S last) const
{
if (first == middle)
{
auto last_it = ranges::next(first, last);
return {last_it, last_it};
}
if (middle == last)
return {std::move(first), std::move(middle)};
if constexpr (std::bidirectional_iterator<I>)
{
ranges::reverse
(注:指定された条件により、HTMLタグ・属性は保持され、
|
例
ranges::rotate
は多くのアルゴリズムで共通して使用される基本構成要素です。この例では
挿入ソート
を実演します。
#include <algorithm> #include <iostream> #include <numeric> #include <string> #include <vector> int main() { std::string s(16, ' '); for (int k {}; k != 5; ++k) { std::iota(s.begin(), s.end(), 'A'); std::ranges::rotate(s, s.begin() + k); std::cout << "Rotate left (" << k << "): " << s << '\n'; } std::cout << '\n'; for (int k {}; k != 5; ++k) { std::iota(s.begin(), s.end(), 'A'); std::ranges::rotate(s, s.end() - k); std::cout << "Rotate right (" << k << "): " << s << '\n'; } std::cout << "\nInsertion sort using `rotate`, step-by-step:\n"; s = {'2', '4', '2', '0', '5', '9', '7', '3', '7', '1'}; for (auto i = s.begin(); i != s.end(); ++i) { std::cout << "i = " << std::ranges::distance(s.begin(), i) << ": "; std::ranges::rotate(std::ranges::upper_bound(s.begin(), i, *i), i, i + 1); std::cout << s << '\n'; } std::cout << (std::ranges::is_sorted(s) ? "Sorted!" : "Not sorted.") << '\n'; }
出力:
Rotate left (0): ABCDEFGHIJKLMNOP Rotate left (1): BCDEFGHIJKLMNOPA Rotate left (2): CDEFGHIJKLMNOPAB Rotate left (3): DEFGHIJKLMNOPABC Rotate left (4): EFGHIJKLMNOPABCD Rotate right (0): ABCDEFGHIJKLMNOP Rotate right (1): PABCDEFGHIJKLMNO Rotate right (2): OPABCDEFGHIJKLMN Rotate right (3): NOPABCDEFGHIJKLM Rotate right (4): MNOPABCDEFGHIJKL Insertion sort using `rotate`, step-by-step: i = 0: 2420597371 i = 1: 2420597371 i = 2: 2240597371 i = 3: 0224597371 i = 4: 0224597371 i = 5: 0224597371 i = 6: 0224579371 i = 7: 0223457971 i = 8: 0223457791 i = 9: 0122345779 Sorted!
関連項目
|
(C++20)
|
要素の範囲をコピーして回転する
(アルゴリズム関数オブジェクト) |
|
(C++20)
|
範囲内の要素の順序を反転する
(アルゴリズム関数オブジェクト) |
|
範囲内の要素の順序を回転する
(関数テンプレート) |