C++ でのシャッフルベクター

胡金庫 2023年10月12日
  1. shuffle アルゴリズムを使用してベクトル要素をシャッフルする
  2. random_shuffle アルゴリズムを用いてベクトル要素をシャッフルする
C++ でのシャッフルベクター

この記事では、C++ でベクトル要素をシャッフルする方法について複数の方法を示します。

shuffle アルゴリズムを使用してベクトル要素をシャッフルする

std::shuffle は C++ の <algorithm> ライブラリの一部であり、与えられた範囲の要素に適用できるランダムな並べ替え機能を実装しています。この関数は、最初の 2つの引数として範囲イテレータを、3 番目の引数として乱数発生器を受け取ります。乱数発生器は関数オブジェクトです。現代の C++ では、乱数生成の標準ライブラリユーティリティの使用を推奨しています。非決定論的な乱数生成には std::random_device を利用すべきです。

最後に、選択した乱数エンジンオブジェクトを作成して shuffle アルゴリズムに渡し、範囲のランダムな順列を生成しなければなりません。シャッフルの前後に整数のベクトルを出力することに注意してください。

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

using std::cin;
using std::cout;
using std::endl;
using std::shuffle;
using std::string;
using std::vector;

template <typename T>
void printVectorElements(vector<T> &vec) {
  for (auto i = 0; i < vec.size(); ++i) {
    cout << vec.at(i) << "; ";
  }
  cout << endl;
}

int main() {
  vector<int> i_vec1 = {12, 32, 43, 53, 23, 65, 84};

  cout << "i_vec1           : ";
  printVectorElements(i_vec1);

  std::random_device rd;
  std::default_random_engine rng(rd());
  shuffle(i_vec1.begin(), i_vec1.end(), rng);

  cout << "i_vec1 (shuffled): ";
  printVectorElements(i_vec1);
  cout << endl;

  return EXIT_SUCCESS;
}

出力:

i_vec1           : 12; 32; 43; 53; 23; 65; 84;
i_vec1 (shuffled): 53; 32; 84; 23; 12; 43; 65;

前述のメソッドの代替として、std::beginstd::end オブジェクトを用いて同じサブルーチンを実装し、範囲のイテレータを shuffle 関数に渡すこともできます。以下の例は、特定のコーディングシナリオのためのより一般的なバージョンです。

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

using std::cin;
using std::cout;
using std::endl;
using std::shuffle;
using std::string;
using std::vector;

template <typename T>
void printVectorElements(vector<T> &vec) {
  for (auto i = 0; i < vec.size(); ++i) {
    cout << vec.at(i) << "; ";
  }
  cout << endl;
}

int main() {
  vector<int> i_vec1 = {12, 32, 43, 53, 23, 65, 84};

  cout << "i_vec1           : ";
  printVectorElements(i_vec1);

  std::random_device rd;
  std::default_random_engine rng(rd());
  shuffle(std::begin(i_vec1), std::end(i_vec1), rng);

  cout << "i_vec1 (shuffled): ";
  printVectorElements(i_vec1);
  cout << endl;

  return EXIT_SUCCESS;
}

出力:

i_vec1           : 12; 32; 43; 53; 23; 65; 84;
i_vec1 (shuffled): 43; 23; 32; 65; 53; 12; 84;

random_shuffle アルゴリズムを用いてベクトル要素をシャッフルする

std::random_shuffle は、C++ 標準ライブラリに含まれるもう一つのユーティリティアルゴリズムです。古いバージョンの std::shuffle は最新の C++ 標準のために減価償却されています。古いバージョンの C++ が利用可能なレガシーなコーディング環境では利用できますが、std::shuffle を利用することはできません。

random_shuffle はユーザが提供する乱数発生器を利用することができますが、古いバージョンの C++ ではランダムライブラリの機能が不足していたため、関数に範囲イテレータのみを提供することもあります。後者の場合、random_shuffle は実装定義の乱数生成器を利用します。

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

using std::cin;
using std::cout;
using std::endl;
using std::shuffle;
using std::string;
using std::vector;

template <typename T>
void printVectorElements(vector<T> &vec) {
  for (auto i = 0; i < vec.size(); ++i) {
    cout << vec.at(i) << "; ";
  }
  cout << endl;
}

int main() {
  vector<int> i_vec1 = {12, 32, 43, 53, 23, 65, 84};

  cout << "i_vec1           : ";
  printVectorElements(i_vec1);

  std::random_shuffle(i_vec1.begin(), i_vec1.end());

  cout << "i_vec1 (shuffled): ";
  printVectorElements(i_vec1);
  cout << endl;

  return EXIT_SUCCESS;
}

出力:

i_vec1           : 12; 32; 43; 53; 23; 65; 84;
i_vec1 (shuffled): 23; 53; 32; 84; 12; 65; 43;
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ Vector