Can percentage probability be done with a switch and ranges in C?
I'm currently using a random number and a series of if statements to assign a pointer to one of four lists using the following:
struct listinfo//struct holds head, tail and the number of entries for the n2l, norm, known and old lists
{
struct vocab * head;
int entries;
struct vocab * tail;
};
...
int list_selector=0;
struct listinfo * currentlist = NULL;
//select a list at random, using the percentage probabilities in the if statements.
//FISH! Can this be done with a switch and ranges?
list_selector = (rand() % 100)+1;
if (list_selector<33) currentlist = &n2l;
if (list_selector>32&&list_selector<95) currentlist=&norm;
if (list_selector>94&&list_selector<100) cur开发者_运维技巧rentlist = &known;
if (list_selector==100) currentlist = &old;
I was just wondering if there's a neater way to do this using ranges in the switch as in this question. If so, an example would be great. Any additional tips would be much appreciated too.
Edit: Fixed! Was linking to wrong page instead of this.
I don't believe C supports ranges in switch statements. You could use an if-else construct to reduce comparisons:
if( x == 100 )
...
else if( x > 94 )
...
And your random number generator is not properly random: RAND_MAX is unlikely to be divisible by 100, so some numbers may be more common than others. Here is the accepted way to convert rand() to a properly random distribution from 1 to 100:
x = 1 + (int) ( 100.0 * ( rand() / ( RAND_MAX + 1.0 ) ) );
As noted before, C doesn't support ranges as switch case selectors. For a compact and efficient form, you could use C's ternary operator, eg:
r = (random() % 100)+1;
currentlist = r<33? &n2l : r<95? &norm : r<100? &known : &old;
or if you prefer could use nested if's, like:
currentlist = &n2l;
if (r>32) {
currentlist = &norm;
if (r>94) {
currentlist = &known;
if (r==100)
currentlist = &old;
}
}
Note, per man rand, "on older rand() implementations... the lower-order bits are much less random than the higher-order bits", so I prefer random() to rand(). Or go with the 100.0 * ( rand() / ( RAND_MAX + 1.0))
formula suggested by asc99c.
No, in this situation, using the less than, greater than, is much more efficient. For a switch, you'd have to outlay all of the different possibilities.
case 1:
2:
3:
4:
/*write all the numbers out all the way up to 31, then for 32 */
32: currentlist = &n2l;
break;
case 33:
34:
35:
/*write out all of these numbers until 94, then for 95 */
95: currentlist=&norm;
break;
/*etc*/
If it's possible to change that (rand() % 100)+1
to provide fewer possible values, you'll have a much easier time with the solution.
If that's not possible, I'm trying to come up with a solution, but it seems like a tricksy problem at first glance (without listing every possible value).
精彩评论