2次元配列のランダマイズについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ポッキー

2次元配列のランダマイズについて

#1

投稿記事 by ポッキー » 12年前

C++言語で配列のランダマイズを勉強(独学)しています。
現在、ある2次元配列からいくつか任意の要素を、2つの配列の要素が対になるように取出して、取り出された要素をランダマイズしたものを出したいと考えています。

例えば、

 a b c d e f g h i j
A  1 2 3 4 5 6 7 8 910
B 11 12 13 14 15 16 17 18 19 20

のように[2][10]配列を組み、ここから5つの要素を取り出すとします。ランダム化の結果、Aの配列からは1,2,6,8,9が選ばれた場合、Bの配列からはAの要素と対になる11,12,16,18,19が同時に選び出されるようにし、取り出された1,2,6,8,9,11,12,16,18,19をさらにランダム化したいのです。

基本的な配列の組み方やそのランダマイズの方法は本やC++言語のサイトで理解できました。これに加えて、上記のように条件を付けて配列・ランダマイズを行うやり方はないかと模索しています。しかし、効率の良い方法が分かりませんでした。やはり配列の各要素に対して、「この要素が選ばれたら自動的に対の要素を選ぶ」といった条件文を書いていくしかないのでしょうか。

当方、独学でCとC++言語を勉強しており、基礎知識はあります。今回のような配列を使い、画像など提示していくようなゲームプログラムができるようになりたいと思っています。
どなたか詳しい方がおりましたら、ご教示くださると助かります。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: 2次元配列のランダマイズについて

#2

投稿記事 by h2so5 » 12年前

2次元配列の各行に対して同じシードを使ってシャッフルを行う、というのが一つの方法だと思います。

コード:

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

int main()
{
    int array[2][10] = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },
 			 { 11, 12, 13, 14,15, 16, 17, 18, 19, 20 } };

    // 乱数のシードを決定
    srand(time(0));
    int seed = rand();

    // 同じシードでシャッフル
    for (int i = 0; i < 2; i++) {
        srand(seed);
        std::random_shuffle(array[i], &array[i][10]);
    }

    // 取り出された数字をまとめる
    std::vector<int> result;
    for (int i = 0; i < 2; i++) {
        // 先頭の5つを取り出す
        result.insert(result.begin(), array[i], &array[i][4]);
    }

    // 取り出された数字をシャッフル
    std::random_shuffle(result.begin(), result.end());

    // 表示 
    for (std::vector<int>::iterator it = result.begin(); it != result.end(); ++it) {
        std::cout << *it << std::endl;
    }

    return 0;
}

アバター
バグ
記事: 130
登録日時: 13年前
住所: 愛媛県
連絡を取る:

Re: 2次元配列のランダマイズについて

#3

投稿記事 by バグ » 12年前

std::pairを使ってはいかがでしょうか?

コード:

#include <vector>
#include <iostream>
#include <algorithm>
#include <ctime>

int main(void)
{
	// 乱数シードの準備
	srand((unsigned)time(NULL));

	// 最初のシャッフル
	std::vector<std::pair<int, int>> vec1 = std::vector<std::pair<int, int>>(10);
	for (int i = 0; i < 10; ++i)
	{
		vec1[i] = std::pair<int, int>(i + 1, i + 11);
	}
	std::random_shuffle(vec1.begin(), vec1.end());

	// 5つのペアを取り出して再シャッフル
	std::vector<int> vec2 = std::vector<int>(10);
	for (int i = 0; i < 10; i += 2)
	{
		vec2[i] = vec1[i].first;
		vec2[i + 1] = vec1[i].second;
	}
	std::random_shuffle(vec2.begin(), vec2.end());

	// 結果を表示
	for (std::vector<int>::iterator it = vec2.begin(); it != vec2.end(); ++it)
	{
		std::cout << *it << std::endl;
	}

	return 0;
}

かずま

Re: 2次元配列のランダマイズについて

#4

投稿記事 by かずま » 12年前

インデックスをシャッフルしてはどうでしょうか?

コード:

#include <iostream>
#include <algorithm>
#include <ctime>

int main()
{
    int a[2][10] = {
        {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10 },
        { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 },
    };
    using namespace std;
    srand(time(0));

    int x[10];
    for (int i = 0; i < 10; i++) x[i] = i;
    random_shuffle(x, x + 10);

    int v[10];
    for (int i = 0; i < 5; i++)
        v[i] = a[0][x[i]],  v[i+5] = a[1][x[i]];
    random_shuffle(v, v + 10);

    for (int i = 0; i < 10; i++) cout << ' ' << v[i];
    endl(cout);
}

ポッキー

Re: 2次元配列のランダマイズについて

#5

投稿記事 by ポッキー » 12年前

みなさん、ありがとうございます。
無事自分でできるようになりました。
STLのmapコンテナにでてくるpairは初めて知ったので、とてもためになりました。
がんばって勉強します。

閉鎖

“C言語何でも質問掲示板” へ戻る