Sign in to follow this  

Randomly Picking from Arrays?

This topic is 4732 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, I'm making a program in C++, and I need some help (if possible). I'm at a point, where I add stuff to an array, and then I need to pick random stuff from that array that I just added stuff to. I'm curious about how i'd do this with Visual C++? I was thinking of looping through each "entry" in the array, then somehow just picking ONE random entry in that array, and adding it to the list, any help would be appreciated..Thank you.

Share this post


Link to post
Share on other sites
You could also do a random shuffle of the array if you don't need to preserve it's initial order:

#include <iostream> // For cout and endl
#include <algorithm> // For random_shuffle
#include <cstdlib> // For srand
#include <ctime> // For time

int main() {
srand ( static_cast<unsigned int>(time(NULL)) );
int array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::random_shuffle ( &array[0], &array[9] );
for ( int i = 0; i < 10; ++i )
std::cout << array[i] << std::endl;
return 0;
}



- Neophyte

Share this post


Link to post
Share on other sites
well, if I did the random shuffle of the array that Neophyte suggested, but then i'd have to reorder it, which I'd like to avoid, so i'm going for graveyard filla's idea. Thank you for the help, ya'll.

Share this post


Link to post
Share on other sites
I'm thinking that you should also be aware that there is anothere difference between the two suggested methods: the first one can produce repetitions, the second one (randomly reordering) will not if you just iterate through it.

Hope it helps.

Share this post


Link to post
Share on other sites
Well, I've decided to go with the first one, the array[rand()%array_size] mostly because it's a dice "System" I am making, and as we all know, dice aren't ALWAYS completely random, so it's fine. I'm just having one problem, how to determine the size of an array? (array[rand()%array_size]) . I can't use strlen, since it's for strings (obviously). Any help would be appreciated, Thank You.

Share this post


Link to post
Share on other sites
As Oluseyi said, you can use Vector instead. That's not neccesary though.
You should know in advance how big your array is. You're the one who allocated it, after all. How big did you make it? Just save that value. :)

Share this post


Link to post
Share on other sites
Actually, the space to be allocated will be different every time. It really depends on what the user inputs for Sides and Rolls. Well, I should go allocate space for it, seeing as how I really forgot to do that first. X_X.

Share this post


Link to post
Share on other sites
Quote:
Original post by Oluseyi
Quote:
Original post by Lenox
I'm just having one problem, how to determine the size of an array?
It can't be done. Use std::vector (and look in <algorithm>; you'll find quite a few useful things in there pertaining to random distribution).

Bah.. Are you completely certain about that? IIRC, there was an example of how to do this in a book I have.. Unfortunately, I don't have the vook with me now, as it's 4 in the morning, and it's not here with me, but I'll see to posting the coe later on if I can find it.

Lenox: You say that a person enters a number for sides, well, just save that number as well as creating an array from it, and you're all set! At least for that problem [smile]

Share this post


Link to post
Share on other sites
Well, I've found a, "workaround" for this problem. I'm totally getting rid of the array, and instead of doing this stuff, I'm going to save the first number (Which, well, will always be 1), and i'm going to save the last number, and i'm going to do :


int A = rand()%End; //End is saved earlier on
return A;



But, then I was wondering if I can specify where to start, as well as where to end? Example :


int A = rand()%Start%End;




Would that one work? I don't want to take the chances of drawing a 0, but then again, I guess if I got a 0, I could just redraw until A ! = 0. Thanks for your help, ya'll. Later! :P

Share this post


Link to post
Share on other sites
OK, let's say you want a number between 3 and 6, inclusive. So, I would do something like this (my syntax may not be perfect here... Long night)

int X = 6; // The higher number
int Y = 3; // The lower number

int Z = ((rand()%((X + 1) - Y)) + Y);


Bah, that is an ugly line of code.. Anyway, basically (and this disection of the code assumes the numbers 6 and 3 for X and Y) the '(rand()%((X + 1) - Y))' will return a value from 0 to 3. Then, you add Y, in this case 3, thus giving you a number from 3 to 6. Clear enough?

Share this post


Link to post
Share on other sites
Couldn't you get the size of an array (as in number of entries) by using sizeof( array ) / sizeof( array[0] ) ?
I've seen that snippet in MS statusbar pane filler code. This assumes that you have at least one entry of course.

Share this post


Link to post
Share on other sites
That works for arrays declared like so: int i[10];
However, it would not work with dynamically allocated arrays: int *i = new int[10];
(sizeof( i ) would return the size of the pointer)

Besides, I think what he meant is how many items there are in the array, not the size of the array itself.

Share this post


Link to post
Share on other sites
Quote:
Original post by Endurion
Couldn't you get the size of an array (as in number of entries) by using sizeof( array ) / sizeof( array[0] ) ?
I've seen that snippet in MS statusbar pane filler code. This assumes that you have at least one entry of course.

Ahh yes, that's the code I was thinking of! However, trick is, I did something like this:

int * x = new int[50];
int y = sizeof(x);
std::cout << y;



And it printed 4. For your method to work, it would have to print, err, 200. I'm thinking the method you say doesn't work for dynamically allocated arrays, only ones like int x[50]; But I could always be wrong.

[EDIT]
Quote:
Besides, I think what he meant is how many items there are in the array, not the size of the array itself.

If you devide the size of the array itself by the size of one element, you get the number of items in the array ;)

Share this post


Link to post
Share on other sites
Quote:
Quote:
Besides, I think what he meant is how many items there are in the array, not the size of the array itself.

If you devide the size of the array itself by the size of one element, you get the number of items in the array ;)


No, the items that were inserted into the array, id est, an array is not always full. So you might have an array of size 10, but only 7 elements in it. And I think he wants to count the number of elements...

Share this post


Link to post
Share on other sites
An array that isn't full? I thought the memory was all allocated when you declared it, either by 'int x[50]' or 'int * x = new int[50]'. You're telling me the memory is not allocated immediately? That's news to me..

Share this post


Link to post
Share on other sites
I'm saying that the array may not be entirely filled with VALID elements.
I'll give an example, maybe it'll clear things up:
int main() {
int i[10];

for( int j = 0; j < 5; ++j )
i[j] = j;

cin.get();
return 0;
}



Do you mean to tell me that i[5] through i[9] have values of interest?

Share this post


Link to post
Share on other sites
Quote:
Original post by jflanglois
I'm saying that the array may not be entirely filled with VALID elements.
I'll give an example, maybe it'll clear things up:
*** Source Snippet Removed ***

Do you mean to tell me that i[5] through i[9] have values of interest?

Fair enough, I didn't cotton on to that, as I tend to initialize my arrays on creation whenever possible. However, in this case, I would think it's probably a safe bet to say that Lenox will be doing that as well, initializing his arrays.

BTW, thanks for pointing that out to me.

Share this post


Link to post
Share on other sites
Quote:
Original post by Oluseyi
Quote:
Original post by Lenox
I'm just having one problem, how to determine the size of an array?
It can't be done.


For a general array, it can be done just fine:


int array[100];
printf( "%d\n", sizeof(array)/sizeof(array[0]) );


Just don't try this on a pointer (which is not an array). If you use pointers as arrays, you have to pass along the size separately, if you don't want to use std::vector<>.

Share this post


Link to post
Share on other sites
Quote:
Original post by SirLuthor
Quote:
Original post by jflanglois
I'm saying that the array may not be entirely filled with VALID elements.
I'll give an example, maybe it'll clear things up:
*** Source Snippet Removed ***

Do you mean to tell me that i[5] through i[9] have values of interest?

Fair enough, I didn't cotton on to that, as I tend to initialize my arrays on creation whenever possible. However, in this case, I would think it's probably a safe bet to say that Lenox will be doing that as well, initializing his arrays.

BTW, thanks for pointing that out to me.


No problem, I just thought that the OP meant it that way, because he has array_size (he did declare his array).

Share this post


Link to post
Share on other sites
Hey, thanks for your help ya'll. I decided to move away from arrays, and go with just making two seperate ints, int Start, and int End. It generates a number between 0 and end, and if Number !=0, then it adds it and stops, else, generates a new number.

Share this post


Link to post
Share on other sites
Hold on a second before you go off working on your own solution for the problem of "generate a random number between two endpoints".

The bit after the % sign is not a magic operator for the rand() call or anything. It is just a bit of arithmetic.

The rand() system call will return a random number over some relatively large range - 0 up to RAND_MAX, whatever that's defined as on your system. (It seems to be 32,767 on most common platforms from what I've heard around here - that is, the largest signed short value.)

'%' is the modulus operator; "x % y" yields the remainder when x is divided by y. This number, of course, has the property that it ranges between 0 and (y-1) inclusive.

So the number you put after the % controls the size of the available range. To get a number in a range where the low end is not 0, just add that value on as an offset.

Share this post


Link to post
Share on other sites
Don't use modulus, it butchers the distribution of rand(). See, lets pretend rand produces numbers between 0 and 100 and you modulus at 60. Then the distribution of the system is weighted towards the numbers 0 through 40 occuring the most, since the mapping would go 60=>0 61=>1 61=>2 ... 99=>39 100=>40. You have two numbers mapping to the first 40 and only 1 mapping to the last 60. Most implementations of rand() attemp to make it that every number in it's range occur at an even chance, so you lose that cleanliness.

Instead, try the following:

x = array[ (int)( ((float)rand()) / (float)RAND_MAX * (float)(sizeof(array)) ) ];

Or, if its a link list:

listnode = listhead;
y = (int)( ((float)rand()) / (float)RAND_MAX * (float)(sizeof(array)) );
while(y--) listnode = listnode->next();

Share this post


Link to post
Share on other sites

This topic is 4732 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this