百分比概率可以用 C 中的开关和范围来完成吗?

发布于 2024-12-01 11:05:31 字数 1081 浏览 1 评论 0原文

我目前正在使用一个随机数和一系列 if 语句,使用以下命令将指针分配给四个列表之一:

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) currentlist = &known;
if (list_selector==100) currentlist = &old;

我只是想知道是否有一种更简洁的方法可以使用开关中的范围来执行此操作,如 < href="https://stackoverflow.com/questions/5839937/switch-statements-and-ranges-of-numbers">这个问题。 如果是这样,一个例子就很好了。任何额外的提示也将不胜感激。

编辑:已修复!链接到错误的页面而不是

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) currentlist = &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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

千寻… 2024-12-08 11:05:31

我不相信 C 支持 switch 语句中的范围。您可以使用 if-else 构造来减少比较:

if( x == 100 )
  ...
else if( x > 94 )
  ...

并且您的随机数生成器不是完全随机的:RAND_MAX 不太可能被 100 整除,因此某些数字可能比其他数字更常见。以下是将 rand() 转换为从 1 到 100 的适当随机分布的公认方法:

x = 1 + (int) ( 100.0 * ( rand() / ( RAND_MAX + 1.0 ) ) );

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 ) ) );
笑梦风尘 2024-12-08 11:05:31

如前所述,C 不支持范围作为 switch case 选择器。对于紧凑且高效的形式,您可以使用 C 的三元运算符,例如:

r = (random() % 100)+1;
currentlist = r<33? &n2l : r<95? &norm : r<100? &known : &old;

或者如果您愿意,可以使用嵌套的 if,例如:

currentlist = &n2l;
if (r>32) {
  currentlist = &norm;
  if (r>94) {
    currentlist = &known;
    if (r==100)
      currentlist = &old;
  }
}

注意,每个人 rand,“在较旧的 rand() 实现上...低位位很多比高阶位的随机性低”,所以我更喜欢 random() 而不是 rand()。或者使用 asc99c 建议的 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.

羁客 2024-12-08 11:05:31

不,在这种情况下,使用小于、大于、效率要高得多。对于转换,您必须花费所有不同的可能性。

   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*/

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*/
夜还是长夜 2024-12-08 11:05:31

如果可以更改 (rand() % 100)+1 以提供更少的可能值,那么您将可以更轻松地解决该问题。

如果这是不可能的,我会尝试想出一个解决方案,但乍一看这似乎是一个棘手的问题(没有列出每个可能的值)。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文