Question:
How would I store, sum and sort 10,000 random numbers C++?
2014-02-15 09:39:34 UTC
Okay, I'm finding this hard to explain in the title so If you're here any help is appreciated.

Basically What I'm trying to do is generate 2 Random numbers between 1-6 which then sum together and become a number between 2-12. I know how to do that. (use Ctime to generate true random number e.t.c.)

I'm confused about how I store these and then total up how many there are of each number. I need to collect 10,000 results and then display an asterix for every 100 of each number so e.g.

2 *
3 **
4 ***
...

My first attempt used Vectors but I later decided that perhaps using an Array may be better as an array doesn't vary in size. OR I'm not sure If i should just use a series of Loops and if statements that assort the numbers into their own arrays/vectors because then I could find the total size of said vector and divide it by 100 to receive the total number of asterix on each number.



Really, I'm utterly confused and I've gotten to the stage of confusion where over-thinking is losing me progress.

What would you suggest?
any help is appreciated.
Four answers:
cja
2014-02-15 16:47:46 UTC
Good answer by _Object, I also recommend you learn about the C++ STL containers, and how to use them. There are many things in the C++ Standard Library that can make your life a lot easier. It's probably also true that you're over-thinking it. You don't need to store the generated numbers, and you don't need to sort them; just store the counts of the number of times they occur. You tried a vector, and that would be ok. You can instantiate a vector and specify an initial size, but that's not much different than just declaring an array. All you need is an array of int, of length 13. I have a feeling you're making this more complicated than it is. It can be as simple as this:



#include

#include

#include

#include

#include



using namespace std;



const int minVal = 1;

const int maxVal = 6;

const size_t N = 10000;

const size_t M = 100;

const char symbol('*');

int random(int minVal, int maxVal);



int main(int argc, char *argv[]) {

    int freq[maxVal * 2 + 1] = { 0 };

    time_t t;

 

    srand((unsigned)time(&t));

    for (size_t i = 0; i < N; i++) {

        ++freq[random(minVal, maxVal) + random(minVal, maxVal)];

    }

    for (int i = minVal * 2; i <= maxVal * 2; i++) {

        cout << setw(2) << setfill('0') << i << " ("

                  << setw(4) << freq[i] << ") "

                  << string(freq[i] / M, symbol) << endl;

    }

    return 0;

}



int random(int minVal, int maxVal) {

    int z = rand() % (maxVal - minVal + 1);

    return minVal + z;

}



#if 0



Sample run:



02 (0296) **

03 (0570) *****

04 (0840) ********

05 (1091) **********

06 (1354) *************

07 (1630) ****************

08 (1389) *************

09 (1161) ***********

10 (0777) *******

11 (0583) *****

12 (0309) ***



#endif
Albert0
2014-02-15 11:01:49 UTC
As I understand it, you need to display how many occurrences there were for each sum value 2 through 12, each sum being formed from two pseudo-random input integers valued between 1 and 6. (FYI, your inputs wil not be truly random... although they will probably be more than random enough.)



This seems to be a binning problem -- you don't actually need to store sums, just counts for each pairwise sum you create. I would do it this way...



//make an array of bins to accumulate frequency of occurrences

create an array of 13 integers

initialize array to all 0s



//randomly generate numbers, incrementing number of occurrences for

//each number as it is generated

for loopindex 1 to 5000

....generate 2 pseudo-ramdom integers valued between 1 and 6 inclusive

....sum the two integers

....increment array[sum]

....next loopindex



//display each generated number value and a star for every 100 occurrences of it

for loopindex 1 to 12

....print loopindex

....starcount = array[loopindex]/100

....for starindex 1 to starcount

........print '*'

........next starindex

....println ()

....next loopindex
?
2014-02-15 12:47:45 UTC
A 6-dimensional array will take 10 000 ^ 6 * sizeof (Number) bytes . Don't do that.



Use a set of pairs- a standard map



std:: map

For each number 1 - 6 generated, add one to the paired value.



This is trivial - you can only generate a total of 6 numbers, so your map will never need more than 6 entries.



STL is powerful if you know how to use it.

Have an example -- follow the link for a formatted version.



http://pastebin.com/t7Qqq7DB



# include

# include

# include

# include

# include



int main (int, char **) {

static const int NumberSamples = 10000;



std:: mt19937 RandEngine {

std:: chrono:: system_clock:: now().time_since_epoch().count()

};



auto Rand = std:: bind (std:: uniform_int_distribution <> {1, 6}, RandEngine);



std:: cout << "Generating random samples...\n";



std:: map DistributionCounter;

for (std:: size_t Sample = 0; Sample < NumberSamples; ++ Sample) {

(DistributionCounter [Rand()]) ++;

}



std:: cout << "Samples collected:\n Results:\n";

for (auto MapIter = DistributionCounter.begin ();

MapIter != DistributionCounter.end (); ++ MapIter) {

std:: cout << " "

<< MapIter -> first

<< ": ";

for (std:: size_t NStars = 0;

NStars < ((MapIter -> second) / 100); NStars ++, std:: cout << "*");



std:: cout << std:: endl;

}



}



Edit: oops, I never actually summed two values. This is trivial -- change

(DistributionCounter [Rand()]) ++;

To

(DistributionCounter [Rand() + Rand()]) ++;

And you will have a working program.



I suppose that I should mention that this was compiled with

g++ -std=c++11 -o test.out test51.cpp
Rance
2014-02-15 10:57:03 UTC
use a six dimension array (one for each number 1-6) to count the number of instances of each random number generated. then use a loop to output the results for each of the 6 possible numbers


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...