开发者

C++ random number from a set

开发者 https://www.devze.com 2022-12-23 09:21 出处:网络
Is it possible to print a random number in C++ from a set of numbers with ONE SINGLE statement? Let\'s say the set is {2, 5, 22, 55, 332}

Is it possible to print a random number in C++ from a set of numbers with ONE SINGLE statement?

Let's say the set is {2, 5, 22, 55, 332}

I looked up rand() but I doubt it开发者_Python百科's possible to do in a single statement.


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


Pointlessly turning things into a single expression is practically what the ternary operator was invented for (I'm having none of litb's compound-statement trickery):

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

Please don't rat on me to my code reviewer.

Ah, here we go, a proper uniform distribution (assuming rand() is uniform on its range) in what you could maybe call a "single statement", at a stretch.

It's an iteration-statement, but then so is a for loop with a great big block containing multiple statements. The syntax doesn't distinguish. This actually contains two statements: the whole thing is a statement, and the whole thing excluding the for(...) part is a statement. So probably "a single statement" means a single expression-statement, which this isn't. But anyway:

// 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.

If this is going to be the only code in the entire program, and you don't want it to return the same value every time, then you need to call srand(). Fortunately this can be fitted in. Change the first line to:

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

Now, let us never speak of this day again.


Say these numbers are in a set of size 5, all you gotta do is find a random value multiplied by 5 (to make it equi probable). Assume the rand() method returns you a random value between range 0 to 1. Multiply the same by 5 and cast it to integer you will get equiprobable values between 0 and 4. Use that to fetch from the index.

I dont know the syntax in C++. But this is how it should look

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

Here I assume rand() is a method that returns a value between 0 and 1.


Yes, it is possible. Not very intuitive but you asked for it:

#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;
}    


Your "single statement" criteria is very vague. Do you mean one machine instruction, one stdlib call?

If you mean one machine instruction, the answer is no, without special hardware.

If you mean one function call, then of course it is possible. You could write a simple function to do what you want:

#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;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消