5

ONE SINGLEステートメントを使用して一連の数値からC++で乱数を出力することは可能ですか?

セットが {2, 5, 22, 55, 332} だとしましょう

rand() を調べましたが、単一のステートメントで実行できるとは思えません。

4

5 に答える 5

11
int numbers[] = { 2, 5, 22, 55, 332 };
int length = sizeof(numbers) / sizeof(int);
int randomNumber = numbers[rand() % length];
于 2010-03-14T19:00:34.627 に答える
5

無意味に単一の式に変換することは、事実上、三項演算子が発明された目的です (私は litb の複合ステートメントの策略を持っていません):

std::cout << ((rand()%5==0) ? 2 : 
              (rand()%4==0) ? 5 : 
              (rand()%3==0) ? 22 : 
              (rand()%2==0) ? 55 : 
              332
             ) << std::endl;

私のコードレビュアーに私を怒らせないでください。

rand()ああ、これで、一気に「単一のステートメント」と呼ぶことができる適切な一様分布 (範囲が一様であると仮定) になります。

これは反復ステートメントですが、複数のステートメントを含む非常に大きなブロックを持つ for ループも同様です。構文は区別しません。for(...)これには実際には 2 つのステートメントが含まれています。全体がステートメントであり、部分を除いた全体がステートメントです。したがって、おそらく「単一のステートメント」は単一の式ステートメントを意味しますが、これはそうではありません。とにかく:

// weasel #1: #define for brevity. If that's against the rules,
// it can be copy and pasted 7 times below.
#define CHUNK ((((unsigned int)RAND_MAX) + 1) / 5)

// weasel #2: for loop lets me define and use a variable in C++ (not C89)
for (unsigned int n = 5*CHUNK; n >= 5*CHUNK;)
    // weasel #3: sequence point in the ternary operator
    ((n = rand()) < CHUNK) ? std::cout << 2 << "\n" :
             (n < 2*CHUNK) ? std::cout << 5 << "\n" :
             (n < 3*CHUNK) ? std::cout << 22 << "\n" :
             (n < 4*CHUNK) ? std::cout << 55 << "\n" :
             (n < 5*CHUNK) ? std::cout << 332 << "\n" :
             (void)0;
             // weasel #4: retry if we get one of the few biggest values
             // that stop us distributing values evenly between 5 options.

これがプログラム全体で唯一のコードになり、毎回同じ値を返したくない場合は、 を呼び出す必要がありますsrand()。幸いなことに、これを組み込むことができます。最初の行を次のように変更します。

for (unsigned int n = (srand((time(0) % UINT_MAX)), 5*CHUNK); n >= 5*CHUNK;)

さて、この日のことは二度と口にしないようにしましょう。

于 2010-03-14T19:29:19.727 に答える
2

これらの数値がサイズ 5 のセットにあるとします。必要なのは、ランダムな値に 5 を掛けた値を見つけることだけです (等確率にするため)。rand() メソッドが 0 から 1 の範囲のランダムな値を返すと仮定します。同じ値に 5 を掛けて整数にキャストすると、0 から 4 の間の等確率の値が得られます。それを使用して、インデックスからフェッチします。

C++ の構文がわかりません。しかし、これはそれがどのように見えるかです

my_rand_val = my_set[(int)(rand()*arr_size)]

ここで、rand() は 0 から 1 の間の値を返すメソッドであると仮定します。

于 2010-03-14T18:59:31.977 に答える
0

はい、可能です。あまり直感的ではありませんが、あなたはそれを求めました:

#include <time.h>
#include <stdlib.h>
#include <iostream>

int main()
{
    srand(time(0));

    int randomNumber = ((int[]) {2, 5, 22, 55, 332})[rand() % 5];

    std::cout << randomNumber << std::endl;

    return 0;
}    
于 2010-03-14T19:03:52.893 に答える
0

あなたの「単一のステートメント」の基準は非常に曖昧です。1 つのマシン命令、1 つの stdlib 呼び出しを意味しますか?

1 つのマシン命令を意味する場合、答えはノーです。特別なハードウェアは必要ありません。

1 つの関数呼び出しを意味する場合は、もちろん可能です。あなたが望むことをするための簡単な関数を書くことができます:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int setSize = 5;
    int set[] = {2, 5, 22, 55, 332 };
    srand( time(0) );

    int number = rand() % setSize;
    printf("%d %d", number, set[number]);
    return 0;
}
于 2010-03-14T19:04:56.140 に答える