Randint issue!

Pages: 12
Mar 25, 2016 at 10:43pm
I'm on the verge of finishing this. I'm having just this one issue.
I'm suppose to loop the rand 1000 from the number 0-10 times and have the stars increment accordingly. (So there should be 1000 stars overall assigned randomly with each cout).

--Right now, I'm testing with just 10 loops----

Yet for days, the I cant figure out why the random gen. keeps outputting starts higher and lower than what I'm inputting. I would very much value some help.

Whats going on with the rand?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{

	int i=0; //It's something between here...
	int numoftest=0;
	int bin[10]={0,0,0,0,0,0,0,0,0,0};
	int num=1;
	srand(time(NULL));
	
	cout <<"How many random number loops (tests) do you want :";
	cin>>numoftest;
 
	while (numoftest > i )
	{	
	i=rand()%10+1; //And here. Should generate numbers between 1-10.  
		
	if (i>=0 && i<1) 
	{bin[0]++;}
	
	else if (i>=1 && i<2) 
	{bin[1]++;}
	
	else if (i>=2 && i<3) 
	{bin[2]++;}
	
	else if (i>=3 && i<4) 
	{bin[3]++;}
	
	else if (i>=4 && i<5) 
	{bin[4]++;}
	
	else if (i>=5 && i<6)
	{bin[5]++;}
	
	else if (i>=6 && i<7)
	{bin[6]++;}
	
	else if (i>=7 && i<8)
	{bin[7]++;}
	
	else if (i>=8 && i<9)
	{bin[8]++;}
	
	else if (i>=9 && i<=10)
	{bin[9]++;}
	
	}

	cout <<num++<<"  "<<bin[0];for(int i=0; i<bin[0];i++) {cout <<"*";}
	cout<<endl;
	cout <<num++<<"  "<<bin[1];for(int i=0; i<bin[1];i++) {cout <<"*";}
	cout<<endl;
	cout <<num++<<"  "<<bin[2];for(int i=0; i<bin[2];i++) {cout <<"*";}
	cout<<endl;
	cout <<num++<<"  "<<bin[3];for(int i=0; i<bin[3];i++) {cout <<"*";}
	cout<<endl;
	cout <<num++<<"  "<<bin[4];for(int i=0; i<bin[4];i++) {cout <<"*";}
	cout<<endl;
	cout <<num++<<"  "<<bin[5];for(int i=0; i<bin[5];i++) {cout <<"*";}
	cout<<endl;
	cout <<num++<<"  "<<bin[6];for(int i=0; i<bin[6];i++) {cout <<"*";}
	cout<<endl;
	cout <<num++<<"  "<<bin[7];for(int i=0; i<bin[7];i++) {cout <<"*";}
	cout<<endl;
	cout <<num++<<"  "<<bin[8];for(int i=0; i<bin[8];i++) {cout <<"*";} 
	cout<<endl;
	cout <<num++<<" "<<bin[9];for(int i=0; i<bin[9]; i++) {cout <<"*";}
	cout<<endl;
	

return 0;
}


Here's a random output:

1
2
3
4
5
6
7
8
9
10
11
How many random number loops (tests) do you want :10
1  0
2  0
3  1*
4  1*
5  2**
6  1*
7  2**
8  0
9  2**
10 2**


Note how its eleven, not ten. I'm getting random outputs despite input. Whats going on with it? I would appreciate the help!
Last edited on Mar 28, 2016 at 6:40am
Mar 26, 2016 at 1:14am
I'm suppose to loop the rand 1000 from the number 0-10 times and have the stars increment accordingly.

Does this mean the user may enter any number from 1 to 1000? That's what I'm guessing, but it isn't what the program is doing.
Mar 26, 2016 at 1:19am
No I'm testing it, from 1-10. Once I get the random func. figured out, I'll kick it up to 1000. Its not exactly necessary to have a cin input. I just need this to loop by a set number. i'm testing 10. But its supposed to be 1000.
Last edited on Mar 26, 2016 at 1:20am
Mar 26, 2016 at 1:37am
Ah, ok thanks.

Well, the while loop at line 18 is repeating the wrong number of times. If numoftest is anything greater than 10 it gives an infinite loop.

You could replace that line:
 
    while (numoftest > i )
with
 
    while (numoftest--)

That should fix the problem. It will continue to repeat until numoftest reaches zero, then the expression will be false and the loop ends.


Also, I should point out that the way the array is used is very clumsy. Imagine if the array had 10000 elements, you'd have to write 20000 lines of code like this:
1
2
    else if (i>=6 && i<7)
        {bin[6]++;}


That entire while loop can be written in just a few two or three lines of code if you use the random number (in the range 0 to 9) as the subscript. bin[rand() % 10]++;

(the output can be simplified with a loop too).
Last edited on Mar 26, 2016 at 1:38am
Mar 26, 2016 at 1:42am
Okay. Yeah I've been told this. I'll try and simplify it with a loop.

Could you show an example of a looped version?

Like for cout, would it be:
1
2
cout <<num<<"  "<<bin[10];for(int i=0; i<=bin[10];i++) {cout <<"*";}
    num++


Anyways I'll try it with the larger numbers.
Last edited on Mar 26, 2016 at 1:48am
Mar 26, 2016 at 2:05am
Regarding the output, the current version does seem to work, it's just the lines like this which are ok
1
2
	cout <<num++<<" "<<bin[9];for(int i=0; i<bin[9]; i++) {cout <<"*";}
	cout<<endl;

but instead of bin[9] , use a variable, like bin[n], then use a loop like:
 
    for (int n=0; n<10; n++)



My apologies if anything I say doesn't make sense, it's getting late where I am and I may be rambling a bit.
Last edited on Mar 26, 2016 at 2:07am
Mar 26, 2016 at 2:09am
Okay. Its good for future reference, in hindsight that was sloppy. Anyway I can turn the histogram vertically? I need an output of 1000 and this isn't going to work. I'm thinking it'll require a lot of mixing around which means I should use the loops instead.

No, you've been quite helpful! I didnt know my problem had such a simple solution. I would rep you if I could!

And I'm attempting to turn these into loops. I need to make the program vertical.
Last edited on Mar 26, 2016 at 2:18am
Mar 26, 2016 at 2:22am
But the output of 1000 will be distributed among ten buckets? I know there is randomness, but on average that's 100 each, not unreasonable, is it?

You could turn it vertically, but it would need a bit of thought. A crude approach would be to use a 2D array, 10 columns by up to 1000 rows. That would work but there could be other ways.
Mar 26, 2016 at 2:26am
I'm going to have to do 10,000 as well. I could try and stretch my cmd but i'd rather not.
If I turn this into a loops it'll be easier.

Would your approach look like this?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
*
*
*
*

Ect?
If so I wouldn't mind trying it. Using 1000's and 10,000's might be bad horizontally.
Last edited on Mar 26, 2016 at 2:27am
Mar 26, 2016 at 2:28am
Code keeps crashing: But I thought I looped it correctly:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
// Keeps freezing
	float i=0; 
	int numoftest=0;
	int n=0;
	int bin[n]={0,0,0,0,0,0,0,0,0,0};
	int num=1;
	srand(time(NULL));
	
	cout <<"How many random number loops (tests) do you want :";
	cin>>numoftest;
 
	while (numoftest--)
	{	
	i=rand() % 2;  
		
	if (n>=0 && n<.1) 
	{bin[0]++;}
	
	else if (n>=1 && n<2) 
	{bin[1]++;}
	
	else if (n>=2 && n<3) 
	{bin[2]++;}
	
	else if (n>=3 && n<4) 
	{bin[3]++;}
	
	else if (n>=4 && n<5) 
	{bin[4]++;}
	
	else if (n>=5 && n<6)
	{bin[5]++;}
	
	else if (n>=6 && n<7)
	{bin[6]++;}
	
	else if (n>=7 && n<8)
	{bin[7]++;}
	
	else if (n>=8 && n<9)
	{bin[8]++;}
	
	else if (n>=9 && n<=1)
	{bin[9]++;}
	
	}

cout <<num++<<" "<<bin[n];for(int n=0; n<10; n++) {cout <<"*";}
	cout<<endl;
	

return 0;
}


Though if its easier to keep the current version, thats fine.
Last edited on Mar 26, 2016 at 2:31am
Mar 26, 2016 at 2:39am
Just a quick comment, I have to go now.
Have you considered using a scaling factor. You could fit it into a specified width (or height) by adjusting the length of the histogram bars in proportion to the space available.

I really have to go now - back tomorrow if necessary.
Mar 26, 2016 at 2:48am
Oh its fine. Its really late where I am anyways.
Mar 26, 2016 at 12:48pm
Code keeps crashing: But I thought I looped it correctly:

That code doesn't compile. I get two errors at line 12.
[Error] ISO C++ forbids variable length array 'bin' [-Wvla]
[Error] variable-sized object 'bin' may not be initialized

The line in question:
11
12
    int n=0;
    int bin[n]={0,0,0,0,0,0,0,0,0,0};


Here int bin[n] n must be a compile-time constant, not a variable.
Second, n has a value of zero. An array with a size of zero is not legal.

You could go back to int bin[10] which would at least be correct. As a matter of good practice, it is usually better to use a defined constant like this:
1
2
	const int size = 10;
	int bin[size] = { 0 }; Set entire array to default value zero

And then everywhere throughout the program where the number 10 was used, change it to size instead.

That way, if you wanted to simulate tossing a coin, size could be changed to 2, or for throwing a die, change it to 6. The rest of the code would not need any changes, simply changing one value allows the program to be reused for different purposes.
Mar 26, 2016 at 3:49pm
Again I really appreciate your help.
Output isnt making sense. Is it due to the while statement?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
	
	int numoftest=0;
	int n=0;
	const int size=10;
	int bin[size]={0};
	int num=1;
	srand(time(NULL));
	
	cout <<"How many random number loops (tests) do you want :";
	cin>>numoftest;
 
	while (numoftest--)
	{	
	n=rand()%10+1;  
		
	if (n>=0 && n<1) 
	{bin[0]++;}
	
	else if (n>=1 && n<2) 
	{bin[1]++;}
	
	else if (n>=2 && n<3) 
	{bin[2]++;}
	
	else if (n>=3 && n<4) 
	{bin[3]++;}
	
	else if (n>=4 && n<5) 
	{bin[4]++;}
	
	else if (n>=5 && n<6)
	{bin[5]++;}
	
	else if (n>=6 && n<7)
	{bin[6]++;}
	
	else if (n>=7 && n<8)
	{bin[7]++;}
	
	else if (n>=8 && n<9)
	{bin[8]++;}
	
	else if (n>=9 && n<=1)
	{bin[9]++;}
	
	}

cout <<num<<" "<<bin[size];for(int n=0; n<10; n++) {cout <<"*";}
	cout<<endl;
	


Or do I need to change my if/else statements?
Again though, if the past code was fine enough to convert to vertical loops then i suppose it isnt necessary. But if its easier to convert it with significantly smaller lines of code, I'm for it.
Last edited on Mar 26, 2016 at 4:07pm
Mar 26, 2016 at 4:25pm
Well, your output statement needs a loop.

Also, I seem to have introduced confusion by suggesting you used the constant size.
Here:
cout <<num<<" "<<bin[size];
the array contains size elements. (i.e. it contains 10 elements since size is 10).
Those elements have subscripts starting from 0 and ending at size-1
(that's the same as saying the valid elements are from bin[0] to bin[9]).
But bin[size] is the same as bin[10], it is the eleventh element. It is not within the array.

Anyway, here's one way I might do it. Please, don't just copy this, try to understand it as well.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    int numoftest = 0;
    const int size = 10;
    int bin[size] = {0};

    srand(time(NULL));
    
    cout << "How many random number loops (tests) do you want :";
    cin >> numoftest;
 
    while (numoftest--)
    {   
        int n = rand()%size;
        
        bin[n] ++;
    }
    
    for (int num=0; num<size; num++)
    {
        cout << num+1 << " " << bin[num];
        for (int n=0; n<bin[num]; n++) 
            cout << "*";
        cout << endl;
    }

    return 0;
}
Last edited on Mar 26, 2016 at 4:25pm
Mar 26, 2016 at 4:47pm
I'm likely to stick with my original code, I'm using these loops mostly for future reference. I need to solidify my knowledge with arrays and incremental loops.

This makes sense. I was using the if/else statements for numerous conditions, my main confusion was how I could assign specific conditions to certain bins without using if/else for each.
Though, I'm still not sure how you did that. What line specifies conditions similar to my if/else statements like (n>1 && n<2)? Everything, especially the incremental make sense.
Mar 26, 2016 at 5:11pm
I'm likely to stick with my original code

If you intend doing that, you should still simplify it.
Take this block of code for example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
	i=rand()%10; 
		
	if (i>=0 && i<1) 
	{bin[0]++;}
	
	else if (i>=1 && i<2) 
	{bin[1]++;}
	
	else if (i>=2 && i<3) 
	{bin[2]++;}
	
	else if (i>=3 && i<4) 
	{bin[3]++;}
	
	else if (i>=4 && i<5) 
	{bin[4]++;}
	
	else if (i>=5 && i<6)
	{bin[5]++;}
	
	else if (i>=6 && i<7)
	{bin[6]++;}
	
	else if (i>=7 && i<8)
	{bin[7]++;}
	
	else if (i>=8 && i<9)
	{bin[8]++;}
	
	else if (i>=9 && i<=10)
	{bin[9]++;}

Just taking one of those if statements as an example,
9
10
	else if (i>=2 && i<3) 
	{bin[2]++;}

Let's see how many possible values of i match that condition. Which integers are greater than or equal to 2 and also less than 3? I can think of just one, the integer 2.
So the code would change to
9
10
	else if (i ==2) 
	{bin[2]++;}


So, if we rewrite that block of code using just the == condition each time, and tidy it up a bit, we get this:
1
2
3
4
5
6
7
8
9
10
11
12
    i = rand()%10; 
        
    if      (i==0) bin[0]++;
    else if (i==1) bin[1]++;
    else if (i==2) bin[2]++;
    else if (i==3) bin[3]++;
    else if (i==4) bin[4]++;
    else if (i==5) bin[5]++;
    else if (i==6) bin[6]++;
    else if (i==7) bin[7]++;
    else if (i==8) bin[8]++;
    else if (i==9) bin[9]++;


That's exactly the same as your original code, but just reformatted a little bit.

Now there's a very clear pattern emerging. Whenever i has a particular value, say 7, then the array element to be incremented has the same number, say bin[7]++

So if the element being incremented is always the same as the value of i. then why not just use i directly?

Hence that same block of code becomes just
1
2
3
    i = rand()%10; 
        
    bin[i]++;


Well, we don't even need i, it merely saves the random number which will be used in just one place, on the very next line, so get rid of i as well and simply write
 
    bin[rand()%10]++;

Last edited on Mar 26, 2016 at 5:13pm
Mar 26, 2016 at 5:43pm
I see. Yeah I'm profusely thankful for the explanation, and I'm fixing up my code a bit. I just dont want to take something that isnt mine without first clearly understanding it and being able to replicate it.

I'm examining this and rewriting my code on these examples. After that I'll try to change it vertical-wise and we'll see what i can come up with.
Last edited on Mar 26, 2016 at 5:44pm
Mar 26, 2016 at 7:00pm
Also, if you wanted to find the numbers 0.1-1. based on the same structure of the array, would it be like this? I got it done my original code, but using loops I'm not sure.

There's also no need to do vertical. I can just condense the stars by dividing their output, supposedly.
Last edited on Mar 26, 2016 at 9:46pm
Mar 26, 2016 at 9:45pm
I got it working with my last code, but the issue seems to be its not increment-ing.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//0.1 to 1.0 version. 
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    int numoftest = 0;
    const int size = 1.0; //Largest number. 
    int bin[size] = {0.0}; //Decimals so I added .0
   

    srand(time(NULL));
    
    cout << "How many random number loops (tests) do you want :";
    cin >> numoftest;
 
    while (numoftest--)
    {   
        int n = (rand()%10)*.1 ; //Get decimals between .1 and 1. 
        
        bin[n] ++;
    }
    
    for (int num=0; num<size; num++)
    {
        cout << num << " " << bin[num];
        for (int n=0; n<bin[num]; n++) 
            cout << "*";
        cout << endl;
    }

    return 0;
}


Output
1
2
3
4
/*
How many random number loops (tests) do you want :10
0 10**********
*/

Last edited on Mar 26, 2016 at 9:47pm
Pages: 12