要素・範囲・オブジェクトを入れ替える関数の説明です。
概要
要素・範囲・オブジェクトの入れ替えを行えます。
範囲の指定方法は、
・std::xxx(C++03): 対象の範囲 [first, last) のイテレータ―を指定します。
・std::ranges::xxx(C++20): 対象の範囲 [first, last) のイテレータ―を指定します。
・std::ranges::xxx(C++20): 対象の範囲を直接指定します。
出力先は、既存の範囲に上書きするものと、別途出力先のイテレーターを指定するものがあります。※
※詳細についてはこちらを参照してください。
https://mappuri.com/program/cpp20-algorithm/
要素・範囲・オブジェクトの入れ替え
iter_swap
2つのイテレーターの要素を入れ替えます。
swap_ranges
2つの範囲を入れ替えます。
同じサイズの範囲が入れ替えられます。範囲2の last が指定されていない場合は範囲1のサイズ、それ以外は範囲1,2の小さいほうのサイズになります。
swap
2つのオブジェクトを入れ替えます。
組み込み型の変数や、配列、STL コンテナなどを指定できます。
iter_swap, swap_ranges, swap のサンプル (C++03, C++11)
#include <iostream>
/** r 内の [first, last) の範囲と値を出力 範囲:[0, 9) 値:1 2 3 4 5 4 5 6 6 */
template<class T, class U, class V>
static void output(T&& r, U&& first, V&& last) {
std::cout << "範囲:[" << std::distance(std::begin(r), first) << ", " << std::distance(std::begin(r), last) << ")";
std::cout << " 値:";
std::string delim = "";
for (auto i = first; i != last; ++i, delim = ", ") {
std::cout << delim << *i;
}
std::cout << std::endl;
}
#include <algorithm>
#include <iostream>
#include <vector>
int main(int argc, char* argv[]) {
{
// 2つのイテレーターの要素を入れ替えます。(C++03)
std::vector<int> r1 = { 1, 2, 3, 4, 5 };
std::vector<int> r2 = { 10, 20, 30, 40, 50, 60 };
std::iter_swap(r1.begin() + 2, r2.begin() + 3);
output(r1, r1.begin(), r1.end()); // 範囲:[0, 5) 値:1, 2, 40, 4, 5
output(r2, r2.begin(), r2.end()); // 範囲:[0, 6) 値:10, 20, 30, 3, 50, 60
}
{
// 2つの範囲を入れ替えます。(C++03)
std::vector<int> r1 = { 1, 2, 3, 4, 5 };
std::vector<int> r2 = { 10, 20, 30, 40, 50, 60 };
std::swap_ranges(r1.begin(), r1.end(), r2.begin());
output(r1, r1.begin(), r1.end()); // 範囲:[0, 5) 値:10, 20, 30, 40, 50
output(r2, r2.begin(), r2.end()); // 範囲:[0, 6) 値:1, 2, 3, 4, 5, 60
}
{
// 2つのオブジェクトを入れ替えます。(C++11)
std::vector<int> r1 = { 1, 2, 3, 4, 5 };
std::vector<int> r2 = { 10, 20, 30, 40, 50, 60 };
std::swap(r1, r2);
output(r1, r1.begin(), r1.end()); // 範囲:[0, 6) 値:10, 20, 30, 40, 50, 60
output(r2, r2.begin(), r2.end()); // 範囲:[0, 5) 値:1, 2, 3, 4, 5
}
return 0;
}
swap_ranges, swap のサンプル (C++20 range)
#include <algorithm>
#include <iostream>
#include <vector>
int main(int argc, char* argv[]) {
{
// 2つの範囲を入れ替えます。(C++20)
std::vector<int> r1 = { 1, 2, 3, 4, 5 };
std::vector<int> r2 = { 10, 20, 30, 40, 50, 60 };
std::ranges::swap_ranges(r1, r2);
output(r1, r1.begin(), r1.end()); // 範囲:[0, 5) 値:10, 20, 30, 40, 50
output(r2, r2.begin(), r2.end()); // 範囲:[0, 6) 値:1, 2, 3, 4, 5, 60
}
{
// 2つのオブジェクトを入れ替えます。(C++20)
std::vector<int> r1 = { 1, 2, 3, 4, 5 };
std::vector<int> r2 = { 10, 20, 30, 40, 50, 60 };
std::ranges::swap(r1, r2);
output(r1, r1.begin(), r1.end()); // 範囲:[0, 6) 値:10, 20, 30, 40, 50, 60
output(r2, r2.begin(), r2.end()); // 範囲:[0, 5) 値:1, 2, 3, 4, 5
}
return 0;
}
要素の入れ替え・抽出
reverse
要素を逆順にします。
reverse_copy
要素を逆順にして出力します。
rotate
要素を指定位置で入れ替えます。
rotate_copy
要素を指定位置で入れ替えて出力します。
shuffle
要素をランダムで並び変えます。
sample
要素をランダムで指定数抽出します。
shift_left
要素を左に移動します。
shift_right
要素を右に移動します。
reverse, rotate, shuffle, sample, shift_left, shift_right, … のサンプル (C++03 – C++20)
#include <algorithm>
#include <iostream>
#include <random>
#include <vector>
int main(int argc, char* argv[]) {
{
// 要素を逆順にします。(C++03)
std::vector<int> r = { 1, 2, 3, 4, 5 };
std::reverse(r.begin(), r.end());
output(r, r.begin(), r.end()); // 範囲:[0, 5) 値:5, 4, 3, 2, 1
}
{
// 要素を逆順にして出力します。(C++03)
std::vector<int> r = { 1, 2, 3, 4, 5 };
std::vector<int> o(r.size());
auto reverse_copy = std::reverse_copy(r.begin(), r.end(), o.begin());
output(o, o.begin(), reverse_copy); // 範囲:[0, 5) 値:5, 4, 3, 2, 1
}
{
// 要素を指定位置で入れ替えます。(C++03)
std::vector<int> r = { 1, 2, 3, 4, 5 };
std::rotate(r.begin(), std::next(r.begin(), 3), r.end());
output(r, r.begin(), r.end()); // 範囲:[0, 5) 値:4, 5, 1, 2, 3
}
{
// 要素を指定位置で入れ替えて出力します。(C++03)
std::vector<int> r = { 1, 2, 3, 4, 5 };
std::vector<int> o(r.size());
auto rotate_copy = std::rotate_copy(r.begin(), std::next(r.begin(), 3), r.end(), o.begin());
output(o, o.begin(), rotate_copy); // 範囲:[0, 5) 値:4, 5, 1, 2, 3
}
{
// 要素をランダムで並び変えます。(C++11)
std::vector<int> r = { 1, 2, 3, 4, 5 };
std::random_device rd;
std::mt19937 re{rd()};
std::shuffle(r.begin(), r.end(), re);
output(r, r.begin(), r.end()); // 範囲:[0, 5) 値:4, 3, 1, 5, 2
}
{
// 要素をランダムで指定数抽出します。(C++17)
std::vector<int> r = { 1, 2, 3, 4, 5 };
std::vector<int> o(r.size());
std::random_device rd;
std::mt19937 re{rd()};
auto sample = std::sample(r.begin(), r.end(), o.begin(), 3, re);
output(o, o.begin(), sample); // 範囲:[0, 3) 値:1, 2, 5
}
{
// 要素を左に移動します。(C++20)
std::vector<int> r = { 1, 2, 3, 4, 5 };
auto shift_left = std::shift_left(r.begin(), r.end(), 3);
output(r, r.begin(), r.end()); // 範囲:[0, 5) 値:4, 5, 3, 4, 5 <- 全体
output(r, r.begin(), shift_left); // 範囲:[0, 2) 値:4, 5 <- 移動後範囲
}
{
// 要素を右に移動します。(C++20)
std::vector<int> r = { 1, 2, 3, 4, 5 };
auto shift_right = std::shift_right(r.begin(), r.end(), 3);
output(r, r.begin(), r.end()); // 範囲:[0, 5) 値:1, 2, 3, 1, 2 <- 全体
output(r, shift_right, r.end()); // 範囲:[3, 5) 値:1, 2 <- 移動後範囲
}
return 0;
}
reverse, rotate, shuffle, sample, … のサンプル (C++20 range)
#include <algorithm>
#include <iostream>
#include <random>
#include <vector>
int main(int argc, char* argv[]) {
{
// 要素を逆順にします。(C++20)
std::vector<int> r = { 1, 2, 3, 4, 5 };
std::ranges::reverse(r);
output(r, r.begin(), r.end()); // 範囲:[0, 5) 値:5, 4, 3, 2, 1
}
{
// 要素を逆順にして出力します。(C++20)
std::vector<int> r = { 1, 2, 3, 4, 5 };
std::vector<int> o(r.size());
auto reverse_copy = std::ranges::reverse_copy(r, o.begin());
output(o, o.begin(), reverse_copy.out); // 範囲:[0, 5) 値:5, 4, 3, 2, 1
}
{
// 要素を指定位置で入れ替えます。(C++20)
std::vector<int> r = { 1, 2, 3, 4, 5 };
std::ranges::rotate(r, std::next(r.begin(), 3));
output(r, r.begin(), r.end()); // 範囲:[0, 5) 値:4, 5, 1, 2, 3
}
{
// 要素を指定位置で入れ替えて出力します。(C++20)
std::vector<int> r = { 1, 2, 3, 4, 5 };
std::vector<int> o(r.size());
auto rotate_copy = std::ranges::rotate_copy(r, std::next(r.begin(), 3), o.begin());
output(o, o.begin(), rotate_copy.out); // 範囲:[0, 5) 値:4, 5, 1, 2, 3
}
{
// 要素をランダムで並び変えます。(C++20)
std::vector<int> r = { 1, 2, 3, 4, 5 };
std::random_device rd;
std::mt19937 re{rd()};
std::ranges::shuffle(r, re);
output(r, r.begin(), r.end()); // 範囲:[0, 5) 値:4, 3, 1, 5, 2
}
{
// 要素をランダムで指定数抽出します。(C++20)
std::vector<int> r = { 1, 2, 3, 4, 5 };
std::vector<int> o(r.size());
std::random_device rd;
std::mt19937 re{rd()};
auto sample = std::ranges::sample(r, o.begin(), 3, re);
output(o, o.begin(), sample); // 範囲:[0, 3) 値:1, 2, 5
}
return 0;
}
コメント