I have to create a program that handles random birthdays between 2 and 50 students (depending on what the user inputs), and calculates the random birthday (1 to 365) and then determines whether or not students share the sam birthday, and how many students share it. I'm stuck on how to get the system to tell me if there are shared birthdays....any ideas?

``````#include <iostream>
#include <fstream>
#include <cmath>
#include <ctime>
using namespace std;

void main()
{
int numStudents, tmp, cnt, i, j;
double Probability, Power;

cout << "Enter Number of Students in The Room: " << endl;
cin >> numStudents;
cout << endl;

int* array=new int[numStudents];

Power = (numStudents * (numStudents - 1)) / 2;
Probability = (1 - pow((364.0)/(365.0) , Power));

cnt = 0;
while (cnt < numStudents)
for (i=0; i < numStudents; i++)
{
array[i] = rand() % 365 + 1;
cout << array[i] << endl;
cnt++;
}
cout << "Number of Students is: " << cnt << endl;
cout << "Probability of sharing DOB: " << Probability << endl;

for(i=0;i < numStudents ;i++)
{
tmp=array[i];
for(int j=0;j<numStudents;j++)
{
if(array[j]==tmp && (j>i))
{
cout << array[j] << endl;
}
}
}

}``````
4
Contributors
17
Replies
21
Views
8 Years
Discussion Span
Last Post by jonsca

Just start j off at i+1. That way you're comparing 0 with all the rest, 1 with from 2 onwards, etc., etc.
If you need to keep track of whether or not you find a birthday more than twice keep the values in an array and check your new entry versus what you already have.

I think you're on the right track

``````for(i=0;i < numStudents ;i++)
{
tmp=array[i];
for(int j=0;j<numStudents;j++)
{
if(array[j]==tmp && (j>i))
{
cout << array[j] << endl;
}
}
}``````

You examine each element of the array, and compare it to all others, looking for a match. Your j>i test with the comparison will prevent flagging previously found matches, but can more simply be done by starting the inner loop at i+1. No need to iterate over what you've already done. (This is substantially similar to the loops for Selection Sort.)

In testing your program, you are probably not seeing the expected results, especially at 23 or more students. You've omitted a critical statement in order get the benefit of (pseudo) randomness in this program - the srand( ) statement.

``srand(unsigned(time(NULL)));``

You need this to execute only once, before you start use of rand( ).

Thank for the code help! However, is there a way to use asterisks or some non-numeric code that shows how many people have that birthday? Right now it will only show what days are shared, but not by how many people...

Edited by PDB1982: n/a

Make yet another array of ints that runs parallel to your duplicate values matrix and increment a particular entry when it comes up more than once. I know how much you enjoy parallel arrays from your other post. The asterisk part should be straightforward from there.

Edited by jonsca: n/a

Make yet another array of ints that runs parallel to your duplicate values matrix and increment a particular entry when it comes up more than once. I know how much you enjoy parallel arrays. The stars part should be straightforward from there.

Better yet, our assignment calls for the following:
"Count up the number of time at least two people have the same birthday, and then divide the by the number of trials to get an estimated probability that two people share the same birthday for a given room size".

So I'm guessing that I wouldn't have to have it printed out necessarily, but how can I have the percentages calculated?

I was thinking saving it into another slot within the array, but I'm not sure if that's the correct way.

Would it be possible to add a

``cnt++``

to the end of the bottom loop, so that when it comes across a match it will add one to a count, and at the end I can take that count and divide it by # of students?

Edited by PDB1982: n/a

Just match them up:

Keep the dates in one `|26|5|140|156|10|` Counts in the other `|1|3|2|6|4|` So the (approximation to the) probability of someone having a birthday on 26th day of the year is 1/(1+3+2+6+4) (but use the 1.0 etc when you enter it)

Edited by jonsca: n/a

Just match them up:

Keep the dates in one `|26|5|140|156|10|` Counts in the other `|1|3|2|6|4|` So the (approximation to the) probability of someone having a birthday on 26th day of the year is 1/(1+3+2+6+4) (but use the 1.0 etc when you enter it)

How would that be coded?

Thank for the code help! However, is there a way to use asterisks or some non-numeric code that shows how many people have that birthday? Right now it will only show what days are shared, but not by how many people...

Keep a counter of how many times a match is found. If you start the inner loop at i+1 as noted previously, you will encounter each pairing just once. Replace your cout statement with an incrementing of the counter.

This will not easily handle the case of triple matches (or more).

Which part?
Well the counts one you should be filling in your code where you were proposing to add cnt++ before (you need to keep track of which date is which in the end so just keeping one number will only get you the total which you can derive from the other array anyway).

So you have an array (you can safely call it of dimension 365 even though you won't need it). Make a second array that has 365 elements to hold the counts.
You find a birthday on the 26.
|26|
You find a birthday on the 122 day
|26|122|
You find a second birthday on the 122, so in your other array you have
|1|2|
Find a birthday on the 200 day
|26|122|200|
other array
|1|2|1|

So now we want to find the probabilities. Probability of the 26 is 1/(1+2+1) = 1/4. Probability of the 122 day is 2/(1+2+1) = 1/2

Yet another way to keep the count:

Have an array of 366, maybe call it `bdays[366]` (one extra to skip day 0)
In your code, `array[]` keeps track of which b'day each person has...

So, if `array[0]` has a b'day on 122, increment it: `bdays[array[0]]++;` You've just counted that b'day.
Next person's b'day on 68 - `bdays[array[1]]++;` etc.

When done, if `bdays[5]` == 3 then 3 people had b'day on day #3.

Yet another way to keep the count:

Have an array of 366, maybe call it `bdays[366]` (one extra to skip day 0)
In your code, `array[]` keeps track of which b'day each person has...

So, if `array[0]` has a b'day on 122, increment it: `bdays[array[0]]++;` You've just counted that b'day.
Next person's b'day on 68 - `bdays[array[1]]++;` etc.

When done, if `bdays[5]` == 3 then 3 people had b'day on day #3.

Would it be inserted like so:

``````for(i=0;i < numStudents ;i++)
{
tmp=array[i];
for(int j=1;j<numStudents;j++)
{
if(array[j]==tmp && (j>i))
{
cout << array[j] << endl;
bdays[array[0]]++;
}

}
}``````

`for(int j=1;j<numStudents;j++)` We've already told you that this is not correct... `bdays[array[0]]++;` You're only updating the count for the day number that is associated with the first element of the array.

`for(int j=1;j<numStudents;j++)` We've already told you that this is not correct... `bdays[array[0]]++;` You're only updating the count for the day number that is associated with the first element of the array.

I corrected the first error, but I'm still confused about the `bdays[array[0]]++;` portion. I'm not sure where to put it, and how it will printout information.

Edited by PDB1982: n/a

If you are working with `array[j]` you need to update `bday[array[j]]`

Yet another way to keep the count:

Have an array of 366, maybe call it `bdays[366]` (one extra to skip day 0)
In your code, `array[]` keeps track of which b'day each person has...

So, if `array[0]` has a b'day on 122, increment it: `bdays[array[0]]++;` You've just counted that b'day.
Next person's b'day on 68 - `bdays[array[1]]++;` etc.

When done, if `bdays[5]` == 3 then 3 people had b'day on day #3.

I think what WaltP was saying and what I was saying has gotten jumbled together. You have to adopt something like the following. Let's assume we have an array, 366 elements long called bdays that goes from day number 1 in slot one (skipping 0) to day 365 in slot 365.
You find a birthday on the 22nd day of the year. The 22 goes into the first array called array. You go to the int value in slot 22 of bdays and you increment it(array[j] is 22, do `bdays[array[j]]++;)` so we're building up these counts.
Then if we encounter a birthday on the 126 day of the year, array[j] = 126 then we go to bdays[array[j]]++; and increment that one.
Initially I was saying line them up so if the first element of the days array was 126 then we'd keep the count for array[j] = 126 in the first slot of the bdays array instead. So the setup can be either

``````|126|73|24|9|239| in the "array" array and
|count126|count73|count24|count9|count239| in the bdays if they line up``````

or

``````|126|73|24|9|239| in the "array" array and
|(count 0)|count 1|count2|count3|count4|count5|count6|count7|count8|+1|count10| etc.  (so 9 is in the proper slot and the others come later -- we've skipped 0 but since the count will be zero it won't affect the result)``````

or even

``````|(1)| | | | | | | | 9|| ||||||||||||||24|||||||| (so filling them in in order as you go)
|count of 1|count of 2|count of 3|... etc.``````

phew I hope the notation is reasonably clear

Edited by jonsca: clear as mud

I think what WaltP was saying and what I was saying has gotten jumbled together. You have to adopt something like the following. Let's assume we have an array, 366 elements long called bdays that goes from day number 1 in slot one (skipping 0) to day 365 in slot 365.
You find a birthday on the 22nd day of the year. The 22 goes into the first array called array. You go to the int value in slot 22 of bdays and you increment it(array[j] is 22, do `bdays[array[j]]++;)` so we're building up these counts.
Then if we encounter a birthday on the 126 day of the year, array[j] = 126 then we go to bdays[array[j]]++; and increment that one.
Initially I was saying line them up so if the first element of the days array was 126 then we'd keep the count for array[j] = 126 in the first slot of the bdays array instead. So the setup can be either

``````|126|73|24|9|239| in the "array" array and
|count126|count73|count24|count9|count239| in the bdays if they line up``````

or

``````|126|73|24|9|239| in the "array" array and
|(count 0)|count 1|count2|count3|count4|count5|count6|count7|count8|+1|count10| etc.  (so 9 is in the proper slot and the others come later -- we've skipped 0 but since the count will be zero it won't affect the result)``````

or even

``````|(1)| | | | | | | | 9|| ||||||||||||||24|||||||| (so filling them in in order as you go)
|count of 1|count of 2|count of 3|... etc.``````

phew I hope the notation is reasonably clear

I completely understand the reasoning, but I'm not sure how to get the numerical values that are stored in the array. I only need a total count for all numbers, not each individual number, unfortunately, which is where I think my disconnect is. I don't understand how to printout that value as one whole number. Wouldn't it be easier to add a counter each time a match is made?

like this:

``````for(i=0;i < numStudents ;i++)
{
tmp=array[i];
for(int j=i+1;j<numStudents;j++)
{
if(array[j]==tmp && (j>i))
{
cout << array[j] << endl;
cnt2++;
}
}
}``````

Edited by PDB1982: n/a

I think I misinterpreted your requirement. You could either go back a step or you can still use what we were just doing.
From your code before:

``````int usednumbers[365];
int filledcount = 0;
int count = 0;
for(i=0;i < numStudents ;i++)
{
tmp=array[i];
for(int j=i+1;j<numStudents;j++)
{
if(array[j]==tmp )
{
if (filledcount >0)
{
[check and see if the number is already in the array and if not add it in and up the count of dates with multiple bdays.  ]
}
else
usednumbers[fillcount] = array[j];
}
double frequency = (double) count /numStudents;``````
This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.