Можно ли сделать процентную вероятность с помощью переключателя и в диапазоне C? - PullRequest
1 голос
/ 27 августа 2011

В настоящее время я использую случайное число и серию операторов 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;

Мне просто интересно, есть ли более удобный способ сделать это, используя диапазоны в коммутаторе, как в этом вопросе. Если это так, пример будет отличным. Любые дополнительные советы также будут высоко оценены.

Редактировать: Исправлено! Ссылка на неправильную страницу вместо this .

Ответы [ 4 ]

3 голосов
/ 27 августа 2011

Я не верю, что 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 ) ) );
1 голос
/ 27 августа 2011

Как отмечалось ранее, C не поддерживает диапазоны в качестве переключателей регистра переключателей.Для компактной и эффективной формы вы можете использовать троичный оператор 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 () ... младшие биты гораздо менее случайны, чем старшие биты», поэтому я предпочитаю random (), а не rand ().Или используйте формулу 100.0 * ( rand() / ( RAND_MAX + 1.0)), предложенную asc99c.

0 голосов
/ 27 августа 2011

Если возможно изменить это значение (rand() % 100)+1, чтобы обеспечить меньшее количество возможных значений, вам будет намного проще найти решение.

Если это невозможно, я пытаюсь придуматьрешение, но на первый взгляд кажется сложной задачей (без перечисления всех возможных значений).

0 голосов
/ 27 августа 2011

Нет, в этой ситуации использование меньше чем, больше чем намного более эффективно.Для переключения вам придется использовать все различные возможности.

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