目次
はじめに
C++でvectorなどのコンテナに格納された要素の並びを、完全に逆順にしたい(例: {1, 2, 3} → {3, 2, 1})場合があります。
この目的のために、標準ライブラリ <algorithm> には、std::reverse と std::reverse_copy という2つの便利な関数が用意されています。
std::reverse: 元のコンテナの要素を、その場で直接、逆順に並べ替えます。std::reverse_copy: 元のコンテナは変更せず、逆順にした結果を別のコンテナにコピーします。
この記事では、これら2つの関数の使い方と違いを、サンプルコードと共に解説します。
reverse / reverse_copy を使ったサンプルコード
このコードは、vectorに格納された文字列の並びを、reverseとreverse_copyの両方で逆順にします。
完成コード
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // reverse, reverse_copy
#include <iterator> // back_inserter
using namespace std;
// vectorの内容を表示するヘルパー関数
void print_vector(const string& title, const vector<string>& vec) {
cout << title << ": ";
for (const auto& item : vec) {
cout << item << " ";
}
cout << endl;
}
int main() {
vector<string> original_items = {"A", "B", "C", "D", "E"};
print_vector("初期状態", original_items);
cout << "--------------------" << endl;
// --- 1. reverse: 元のコンテナを直接、逆順にする ---
vector<string> in_place_reversed = original_items; // コピーを作成
reverse(in_place_reversed.begin(), in_place_reversed.end());
print_vector("reverse (インプレース)", in_place_reversed);
// --- 2. reverse_copy: 元のコンテナは変えずに、結果を別のコンテナにコピー ---
vector<string> copied_reversed;
reverse_copy(original_items.begin(), original_items.end(),
back_inserter(copied_reversed));
print_vector("reverse_copy (コピー)", copied_reversed);
// 元のコンテナが変更されていないことを確認
print_vector("reverse_copy後の初期状態", original_items);
return 0;
}
実行結果
初期状態: A B C D E
--------------------
reverse (インプレース): E D C B A
reverse_copy (コピー): E D C B A
reverse_copy後の初期状態: A B C D E
コードの解説
1. std::reverse
reverse(範囲の開始イテレータ, 範囲の終了イテレータ);
- 機能: 引数で指定された範囲内の要素を、**その場で(in-place)**逆順に並べ替えます。元のコンテナが直接変更されます。
- 使いどころ: 元の順序を保持する必要がなく、メモリを節約したい場合に適しています。
2. std::reverse_copy
reverse_copy(入力範囲の開始, 入力範囲の終了, 出力先の開始イテレータ);
- 機能: 入力範囲の要素を逆順に並べ替えますが、その結果を新しい出力先にコピーします。元のコンテナは一切変更されません。
back_inserter(copied_reversed): 結果をcopied_reversedベクターの末尾に.push_back()で追加していくための特殊なイテレータです。- 使いどころ: 元のデータの順序を保持したまま、逆順のコピーが欲しい場合に利用します。
まとめ
今回は、C++の <algorithm> ライブラリが提供する、コンテナの要素を逆順にする2つの関数を解説しました。
std::reverse: 破壊的。元のコンテナを直接書き換える。std::reverse_copy: 非破壊的。元のコンテナは変えずに、結果をコピーする。
どちらの関数も、コンテナの種類を問わず(vector, list, arrayなど)、双方向イテレータを持つものであれば利用できます。目的に応じて適切に使い分けましょう。
