C++: How to generate a random number from an array [duplicate] - c++

This question already has answers here:
How to get a random element from a C++ container?
(9 answers)
Closed 7 years ago.
I´ve an array which stores 5 inputs (int), in a guessing-game.
What I would like to do is to generate a random number (pick one of five numbers which is stored) from that array, can anyone help me with this?
I'm familliar with the rand-fuction but only to pick a random number within a range och numbers, not between 5 inputs...

Use e.g. std::uniform_int_distribution to get a value between 0 and 4 (inclusive) and use that as an index into the array.

Assuming your array object is int arr[5] then you can use one of the following ways depending on C++ version you are using.
All versions of C++:
int random_number = arr[rand() % 5];
Keep in mind that this solution suffers from bias issues. If you want to achive good distribution of generated numbers with this way then read following answer to the same question: https://stackoverflow.com/a/6943003/1289981
Since C++11 (most correct way):
std::random_device rd;
std::default_random_engine e1(rd());
std::uniform_int_distribution<int> uniform_dist(0, 4);
int random_number = arr[uniform_dist(e1)];

Simply use a random number generator to generate a number from 0,1,2,3,4 and use that number as index in your array, obviously.
rand is something that we typically discourage people from using, as it's not thread-safe. However, in your simple case, it should work.

You can simply generate a random number x from 0 to length of an array - 1, and then pick the x-th number from it.
Something like this:
int x = rand() % 5;
cout << inputs[x]; // here is your value

This sounds like course work so without giving you the answer directly, the logic you need to follow is-
Generate a random number that is the in the range of your input array:
0 to ( [number of inputs] - 1 )
in your case that would be 0 to 4.
Make sure to store the random number into a variable e.g. a variable called randonInput
Then you select from the array using the number generated, i.e:
int randomInput = inputArray[randomNumber];
Then you will have the random input stored in the randomInput variable

Related

Range of random numbers as applied to array of words

I am very new to C++. I am basically self teaching. I came across a Hangman game project that I am using for practice. My problem is to do with the random word generation.
I know that for example int n=rand()% 10 means generate random numbers from range 0 to 10.
Now in the game there is an array with 10 elements for the ten words. What I am confused about is that if numbers from 0 to 10 is randomly generated, that would be a selection from 11 random numbers. However the array only has 10 elements (0-9).
What happens when the random generator chooses 10? Element 10 does not exist in the array, right?
So should this code not have been int n=rand()% 9 instead?
Also, could the same word be repeated before all words have been selected in the game? That would obviously not be ideal. If it could, then how do I prevent this?
I know that for example int n=rand()% 10 means generate random numbers
from range 0 to 10.
Not exactly. Generated range is then [0,9].
Side note: in C++11 you should use better random number generator: std::uniform_int_distribution
#include <random>
#include <iostream>
int main()
{
std::random_device rd;
std::mt19937 gen( rd());
// here (0,9) means endpoints included (this is a call to constructor)
std::uniform_int_distribution<> dis(0, 9);
std::cout << dis(gen) << std::endl; // std::endl forces std::cout to
// flush it's content, you may use '\n'
// instead to buffer content
return 0;
}
If you try to subscript array with out-of-range index then it is a disaster named Undefined Behavior:
Undefined behavior and sequence points
What are all the common undefined behaviours that a C++ programmer should know about?
You misunderstand ranges and modulus in C/C++: Ranges include the first element, but (usually) not the last element. Hence, the range [0, 10) is 0,1,2,3,...,9.The modulus is mathematical, the expression x % 10 clamps the result to the range [0, 10), which is 0,1,2,3,...,9

Use entire list in pseudo-random number generation [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Pseudo-Random Traversal of a Set
I'm trying to write an algorithm that will put the songs of a playlist into a random order, so if there are 10 songs, I need the random number generator to hit every value from 0-9 before repeating. Using the algorithm: x_current = (a * x_prev + c) mod m, is there any way to achieve this with certain values for a c and m?
Try using std::random_shuffle
vector<int> playOrder;
// set some values:
for (int i=1; i<10; ++i) playOrder.push_back(i); // 1 2 3 4 5 6 7 8 9
// Don't forget to seed, or mix will be the same each run
srand(time(NULL));
// using built-in random generator:
random_shuffle ( playOrder.begin(), playOrder.end() );
// An example of how you might use the new random array.
for(int i=0; i<playOrder.size(); i++)
player.PlayTrack(playOrder[i]);
Take a look at this question. Also, for small playlists, simply shuffling an array with the song numbers will be sufficient.

Advice on a simple random number generation problem.

I have a simple integer vector, with only 4 values. I want to loop through the vector, assigning either 0 or 1 to each value. I want it to be random to the point that its different every time.
I thought the following would suffice:
for (int i = 0; i < (int)numberVect.size(); i++)
{
numberVect[i] = rand() % 2;
}
However, what I found was that every time I would close and re-open the program, the exact same values would be assigned.
So the first time through it would be 1,0,0,0, then if I ran the loop again without closing the program it would be 0,1,0,1. which seems perfect.
HOWEVER, after closing the program and restarting it up again, I would find the first sequence would again be 1,0,0,0 and the second would again be 0,1,0,1.
Also I have a second question in relation to this problem:
Can you suggest a way to make sure that AT LEAST one of the values in the vector is a 1? while still allowing the random generation to work seamlessly?
Thanks a lot and I hope you guys can help :D
Question 1
You need to seed your random number generator with srand.
The sequence of pseudo-random numbers generated depends on the seed value (and are thus reproducible with the same seed value). I use the the current time as the seed value:
srand(time(NULL));
Question 2
There are only 16 possible sequences for you to choose from (4 bits).
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
Out of these, you want to randomly select one with at least 1 high bit. Therefore you just need to randomly select a number from 1 to 15 and then convert it to binary!
There are two ways of doing this:
Method 1:
int R = rand() % 15 + 1;
Method 2:
float r = static_cast<float>(rand())/RAND_MAX;
int R = static_cast<int>( ceil(1 + (15-1)*r) );
Once you have R, convert it to binary. Here's a sample program with Method 1:
// Seed the random number generator
srand(static_cast<unsigned int>(time(NULL)));
// Get the random number from 1 - 15
int R = (rand()%15)+1;
cout<<R<<endl;
// Convert to binary
vector<int> numberVect(4);
for (int i = static_cast<int>(numberVect.size())-1; i >=0 ; i--)
{
numberVect[i] = R%2;
R/=2;
}
// Display
cout<<numberVect[0]<<","<<numberVect[1]<<","<<numberVect[2]<<","<<numberVect[3]<<endl;
Note: static_cast<int>(x) is the C++ way of doing (int)x if you didn't know.
You should seed your random generator with the current time at program start to avoid this behaviour.
You need to seed the random generator, before using it. For that you need srand()
I usually do that with passing current time to srand() as:
#include <time.h>
srand(time(NULL)); //seeding!
//now use
int whatever = rand();
Now everytime, you run this code you'll get different random sequence,even if there is one second of difference between two consecutive runs.
You need to seed your random numbers. Using the time is common practice.
Do this in your program before you generate any random numbers:
srand(time(NULL));
The random number generator isn't "truly random", it needs to start somewhere, and typically people will use the current system time as a good "kinda random" start point, guaranteeing that each run of the program will be different.
Your second question: can you make sure that at least one of the values is a "1" while still being random? Well, no, of course not, then it wouldn't be random. :) You can post-process, though, if you're willing to forgo some of the "randomness"-- after you generate the vector, check to see if there's at least one "1" value. If not, set one of them to "1". :)
You have to initialize the random seed. Include stdlib.h and time.h, then call this before calling rand() for the first time:
srand(time(NULL));
This code initializes the random seed with the current system time, in seconds, so you always get different results (unless you start the program twice during one second.)
You're getting the same results each time you run the program because you aren't seeding rand. It's usually recommended to seed based on time:
srand(time(NULL));
To make sure at least 1 number is 1, you could use a bool to indicate if you've gotten a 1 yet. If at the end of the array, you don't have a 1, do a final call to rand with a mod of the vector size, and set that value to 1.

How do I generate totally a random number at a time?

I want to create 3 random number at a time (simultaneously). However, they returned me the same numbers at a time even though they are actually random. Example:
------------------------
Variable: A B C
------------------------
Time 1 : 5 5 5
Time 2 : 3 3 3
Time 3 : 9 9 9
------------------------
They suppose to be different numbers at all. From the observation, I can see that my code can only pick a random number at a time (interval 1 second). Here is my generator code that I'm using:
unsigned int CMain::GenerateRandom(int min, int max)
{
srand((unsigned)time(0));
unsigned int random_integer;
int lowest = min, highest = max;
int range = (highest - lowest) + 1;
random_integer = lowest + int(range * rand() / (RAND_MAX + 1.0));
return random_integer;
}
How could I generate a totally random numbers at a time? Please help.
Thank you.
Your issue here is you're resetting the random seed every call using the current time which you shouldn't do.
Call srand() once before querying any random numbers - that's all and more than enough.
Right now you always reset your random seed to the exact same value (as you use current time). Random numbers in PCs aren't really random at all. The same seed will always result in the same set of random numbers generated later on. This is intentional and used in e.g. savegames for games to always have the same things happen without having to save every random number generated, etc.
Don't call srand() each time you generate a new random number. Call it once at the start of your program and then just call rand() each time you need a new random number.
FYI: Values returned from rand() are not "totally random". They are pseudo-random numbers generated by an algorithm. (This is not related to your question though.)
The problem is that you are calling srand() for every iteration. Srand() is setting a seed based on the current timestamp. Therefore you only need to call srand() once, and just call rand() to generate a new pseudo-random number. I say pseudo-random because computers cannot generate truly random numbers.
Sample code:
#include <iostream>
#include <cstdlib>
int main()
{
int i, r;
srand(time(0));
for(i = 0; r <= 20000; i++)
r = rand();
return 0;
}
time(0) changes slowly. If you query GenerateRandom quickly you can get the same number multiple times.
But in general, that isn't a right way to generate random numbers. You want to seed the random number generator only once, before any other function uses it. Treat rand as a global singleton object. If any of your functions modifies its seed by calling srand, then the change will affect all other calls to rand.

Random integers c++

I'm trying to produce random integers (uniformly distributed).
I found this snippet on an other forum but it works in a very weird way..
srand(time(NULL));
AB=rand() % 10+1;
Using this method I get values in a cycle so the value increases with every call until it goes down again. I guess this has something to do with using the time as aninitializer?
Something like this comes out.
1 3 5 6 9 1 4 5 7 8 1 2 4 6 7.
I would however like to get totally random numbers like
1 9 1 3 8 2 1 7 6 7 5...
Thanks for any help
You should call srand() only once per program.
Also check out the Boost Random Number Library:
Boost Random Number Library
srand() has to be done once per execution, not once for each rand() call,
some random number generators have a problem with using "low digit", and there is a bias
if you don't drop some number, a possible work around for both issues:
int alea(int n){
assert (0 < n && n <= RAND_MAX);
int partSize =
n == RAND_MAX ? 1 : 1 + (RAND_MAX-n)/(n+1);
int maxUsefull = partSize * n + (partSize-1);
int draw;
do {
draw = rand();
} while (draw > maxUsefull);
return draw/partSize;
}
You can use the the Park-Miller "minimal standard" Linear Congruential Generator (LCG): (seed * 16807 mod(2^31 - 1)). My implementation is here
Random integers with g++ 4.4.5
The C language 'srand()' function is used to set the global variable that 'rand()' uses. When you need a single sequence of random numbers, 'rand()' is more than enough, but oftentimes you need several random number generators. For those cases, my advice would be to use C++ and a class like 'rand31pmc'.
If you want to generate random numbers in a small range, then you can use the Java library implementation available here:
http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt%28int%29