5

次のように [0, 10] の範囲で乱数を生成する必要があります。

  • すべての数字は 1 回出現します。
  • 繰り返し結果は得られません。

誰かがどのアルゴリズムを使用するか教えてもらえますか?

4

3 に答える 3

11

Richard J. Ross の回答のアルゴリズムは正しくありません。n^nの代わりに可能な順序付けを生成しn!ます。Jeff Atwood のブログのこの投稿は、問題を示しています。

代わりに、Knuth-Fisher-Yates Shuffle を使用する必要があります。

int values[11] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
srand(time(NULL));

for (int i = 10; i > 0; i--)
{
    int n = rand() % (i + 1);

    int temp = values[n];
    values[n] = values[i];
    values[i] = temp;
}
于 2012-07-03T18:02:55.647 に答える
1

疑似乱数に対してこのアルゴリズムを試してください。

int values[11] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
srand(time(NULL));

for (int i = 0; i < 11; i++)
{
    int swap1idx = rand() % 11;
    int swap2idx = rand() % 11;

    int tmp = values[swap1idx];
    values[swap1idx] = values[swap2idx];
    values[swap2idx] = tmp;
}

// now you can iterate through the shuffled values array.

これはモジュロバイアスの影響を受けることに注意してくださいが、必要なものに対しては機能するはずです。

于 2012-07-03T17:44:05.697 に答える
0

次のようなランダム化関数を作成してみてください。

void randomize(int v[], int size, int r_max) {
    int i,j,flag;

    v[0] = 0 + rand() % r_max; // start + rand() % end
    /* the following cycle manages, discarding it,
the case in which a number who has previously been extracted, is re-extracted. */
    for(i = 1; i < size; i++) {
        do {
            v[i]= 0 + rand() % r_max;
            for(j=0; j<i; j++) {
                if(v[j] == v[i]) {
                    flag=1;
                    break;
                }
                flag=0;
            }
        } while(flag == 1);
    }
}

v[]次に、 11個の要素の配列、そのサイズ、および上限範囲を渡して、それを呼び出すだけです。

randomize(v, 11, 11);

配列は、参照によって引数として渡されるため、ランダム化され、繰り返しはなく、数値は1回だけ発生します。

srand(time(0));を呼び出す前に呼び出すことrandomize、および初期化することを忘れないでくださいint v[11]={0,1,2,3,4,5,6,7,8,9,10};

于 2012-07-03T18:27:44.427 に答える