[C++]リストをシャッフルしてランダムに並び替えるには?

C++

どうも、ちょげ(@chogetarou)です。

リスト(List)をシャッフルしてランダムに並び替える方法を紹介します。

スポンサーリンク

方法

インターフェース, インターネット, プログラム, ブラウザ, Www

リスト(List)をシャッフルしてランダムに並び替える方法は、3つあります。

for文

1つ目は、for文を使う方法です。

まず、for文でリストのインデックスを逆順でループします。

ループ処理で、rand()を「ループ変数に1を足した値」で割った余りを取得します。

次に、swap()を呼び出します。

そして、swap()の第1引数に「リストのループ変数のインデックスの要素」、第2引数に「リストの取得した余りのインデックスの要素」を指定します。

//myList=対象のリスト
int length = myList.size(); //リストの要素を取得
    for (int i = length - 1; i >= 0; --i) {
        int j = rand() % (i + 1); //リストのランダムなインデックスを取得
        swap(*next(myList.begin(), i), *next(myList.begin(), j)); //リストの要素を入れ替える
    }

上記のfor文は、リストの要素をシャッフルしてランダムに並び替えます。

使用例

#include <iostream>
#include <list>
#include <ctime>
using namespace std;

int main(void){
    
    list<string> nums = { "one", "two", "three", "four", "five"};
    
    srand(time(NULL));
    int length = nums.size();
    for (int i = length - 1; i >= 0; --i) {
        int j = rand() % (i + 1);
        swap(*next(nums.begin(), i), *next(nums.begin(), j));
    }
    
    
    for(string item: nums) {
        cout << item << endl;
    }
    
    return 0;
}
出力:
three
one
four
two
five

random_shuffle()

2つ目は、ranadom_shuffle()を使う方法です。

まず、algorithmをインクルードします。

#include <algorithm>

次に、リストをVectorに変換し、random_shuffle()を呼び出します。

random_shuffle()の第1引数にVectorのイテレータの先頭、第2引数にVectorのイテレータの末尾を指定します。

最後に、copy()を呼び出します。

copy()の第1引数にVectorのイテレータの先頭、第2引数にVectorのイテレータの末尾を指定します。

そして、copy()の第3引数にリストのイテレータの先頭を指定します。

//T=リストの要素の型, myList=対象のリスト
vector<T> vec(myList.begin(), myList.end());
random_shuffle(vec.begin(), vec.end());
copy(vec.begin(), vec.end(), myList.begin());

上記のrandom_shuffle()は、リスト(List)の要素をシャッフルしてランダムに並び替えます。

使用例

#include <iostream>
#include <list>
#include <algorithm>
#include <ctime>
using namespace std;

int main(void){
    
    list<string> nums = { "one", "two", "three", "four", "five"};
    
    
    vector<string> vec(nums.begin(), nums.end());
    random_shuffle(vec.begin(), vec.end());
    copy(vec.begin(), vec.end(), nums.begin());
    
    for(string item: nums) {
        cout << item << endl;
    }
    
    return 0;
}
出力:
five
four
two
three
one

shuffle()

3つ目は、shuffle()を使う方法です。

まず、randomをインクルードします。

#include <random>

次に、リストをVectorに変換し、shuffle()を呼び出します。

shuffle()の第1引数にVectorのイテレータの先頭、第2引数にVectorのイテレータの末尾を指定します。

shuffle()の第3引数にstd::default_random_engine()を指定します。

最後に、copy()を呼び出します。

copy()の第1引数にVectorのイテレータの先頭、第2引数にVectorのイテレータの末尾を指定します。

そして、copy()の第3引数にリストのイテレータの先頭を指定します。

//T=リストの要素の型, myList=対象のリスト
vector<T> vec(myList.begin(), myList.end()); //リストをVectorに変換
shuffle(vec.begin(), vec.end(), default_random_engine(time())); //Vectorをシャッフル
copy(vec.begin(), vec.end(), myList.begin()); //Vectorを元のリストにコピー

上記のshuffle()は、リストの要素をシャッフルしてランダムに並び替えます。

std::default_random_engine()は、引数にシードを指定できます。

使用例

#include <iostream>
#include <list>
#include <random>
#include <ctime>
using namespace std;

int main(void){
    
    list<string> nums = { "one", "two", "three", "four", "five"};
    
    
    vector<string> vec(nums.begin(), nums.end());
    shuffle(vec.begin(), vec.end(), default_random_engine(time(NULL)));
    copy(vec.begin(), vec.end(), nums.begin());
    
    for(string item: nums) {
        cout << item << endl;
    }
    
    return 0;
}
出力:
three
four
two
one
five
スポンサーリンク

まとめ

リスト(List)をシャッフルしてランダムに並び替える方法は、次の3つです。

  • for文を使う方法
  • random_shuffle()を使う方法
    vector<T> vec(myList.begin(), myList.end());
    random_shuffle(vec.begin(), vec.end());
    copy(vec.begin(), vec.end(), myList.begin());
  • shuffle()を使う方法
    vector<T> vec(myList.begin(), myList.end()); //リストをVectorに変換
    shuffle(vec.begin(), vec.end(), default_random_engine(time())); //Vectorをシャッフル
    copy(vec.begin(), vec.end(), myList.begin()); //Vectorを元のリストにコピー

コメント

タイトルとURLをコピーしました