Не генерируйте одно и то же случайное число в C + - 2 - PullRequest
0 голосов
/ 03 мая 2019
srand(time(NULL));

for(i = 0; i < 100; i++)
{
   int randomNumber = (rand() % 100) + 1  // gets a random number from 0 - 100.
   // do stuff
}

В настоящее время у меня есть переменная случайного числа, которая хранит число от 0 до 100 в каждой итерации цикла for, и код ниже затем работает с этой переменной случайного числа.Однако я заметил, что на каждой итерации цикла иногда генерируется одно и то же случайное число, а иногда оно генерирует число, очень близкое к тому, которое я уже сгенерировал.Например: когда
i = 1 randomNumber может быть 50, но когда i = 2, это может быть 51. Это очень раздражает то, что я кодирую.Есть ли способ, которым я могу сделать так, что если он генерирует 50 в первый раз, во второй раз он должен сгенерировать целые числа 2 от того, который он только что сгенерировал.Например, если он просто генерирует 50, то во второй раз он не может генерировать 48,49,50,51,52, но он все равно генерирует между 0-100, просто пропуская эти числа.Затем он повторяет то же самое, когда генерируется новый randomNumber.

Ответы [ 2 ]

2 голосов
/ 03 мая 2019

Самый простой способ - получить случайное число в цикле, которое проверяет, слишком ли оно близко к последнему числу.

srand(time(NULL));
int lastRandom = -2;
for(int i = 0; i < 100; i++)
{
    int randomNumber;
    do {
        randomNumber = (rand() % 100) + 1;  // gets a random number from 0 - 100.
    } while (randomNumber >= lastRandom - 2 && randomNumber <= lastRandom + 2);
    lastRandom = randomNumber;
    // do stuff
}

Обычно я бы не советовал вызывать rand() в цикле, потому чтоэто может продолжаться слишком долго, если критерии принятия слишком строгие.Но это отклоняет только около 5%, поэтому вряд ли будет повторяться много раз.

1 голос
/ 04 мая 2019

Что вы можете сделать, если вы не возражаете получить один и тот же номер более одного раза (если его нет в строке), но вам не нужен внутренний цикл, который пытается получить новый номер, это:

  1. Получить случайное число от 1 до 100 обычно в первом цикле.

  2. После этого, добавив случайное число от 3 до 97 к последнему числу, а затем используя модуль 100, вы получите случайное число в диапазоне от 1 до 100, исключая числа в диапазоне от oldNum - 2 до * 1010. *.

    (Обратите внимание, что это оборачивает диапазон исключенных номеров, так что, например, если последнее число было 100, то 1 и 2 также будут исключены).

srand(time(NULL));

int randomNumber;
for(i = 0; i < 100; i++) {
   if (i == 0) {
       randomNumber = (rand() % 100) + 1;  // gets a random number from 1 - 100.
   } else {
       randomNumber = ((randomNumber + (rand() % 95) + 3) % 100) + 1;
   }
   // do stuff
}

Если вы не хотите, чтобы список исключенных номеров был перенесен (например, если последний номер был 99, то вы бы хотели исключить только 97, 98, 99 и 100), тогда это немного сложнее:

  1. Вы все еще хотите получить случайное число от 1 до 100 обычно в первом цикле.

  2. После этого по умолчанию будет добавлено случайное число от 3 до 97 к последнему числу, а затем по модулю 100 вы получите случайное число в диапазоне от 1 до 100, исключая числа в диапазоне oldNum - 2 до oldNum + 2.

    Но прежде чем перейти к настройкам по умолчанию, вам нужно проверить, является ли старое число настолько низким или настолько высоким, что диапазон исключенных чисел будет охватывать:

    а. Если старое число настолько мало, что диапазон исключенных чисел будет перенесен, нам нужно случайное число в диапазоне от oldNum + 3 до 100.

    б. Если старое число настолько велико, что диапазон исключенных чисел будет перенесен, нам нужно случайное число в диапазоне от 1 до oldNum - 3.

srand(time(NULL));

int randomNumber;
for(i = 0; i < 100; i++) {
   if (i == 0) {
       randomNumber = (rand() % 100) + 1;  // gets a random number from 1 - 100.
   } else {
        if (randomNumber < 3) {
        /* Old number is so low that excluded numbers would wrap if we would
         * be using the 'default' way.
         * We want a random number in the range from randomNumber + 3 to 100:
         */
            randomNumber += (rand() % (98 - randomNumber)) + 3; 
        }
        else if (randomNumber > 98) {
        /* Old number is so high that excluded numbers would wrap if we would
         * be using the 'default' way.
         * We want a random number in the range from 1 to randomNumber - 3:
         */
            randomNumber = (rand() % (randomNumber - 3)) + 1; 
        } else {
        /* Default way. 
         * We want a random number in the range 1 to 100, excluding numbers in the 
         * range randomNumber - 2 to randomNumber + 2
         */
            randomNumber = ((randomNumber + (rand() % 95) + 3) % 100) + 1;
        }
   }
   // do stuff
}

Если у кого-то есть такая же проблема, но он хочет, чтобы число в другом диапазоне и / или хотело, чтобы диапазон исключаемых чисел был другим, вот тот же код, но с константами вместо «магических чисел»:

srand(time(NULL));

int randomNumber;
int const maxNum = 100; // Random number must be in the range from 1 to maxNum
int const exclude = 2;  // New random number must NOT be in the range
                        // from (oldNum - exclude) to (oldNum + exclude)
for(i = 0; i < 100; i++) {
   if (i == 0) {
       randomNumber = (rand() % maxNum) + 1;  // gets a random number from 1 to maxNum.
   } else {
        if (randomNumber <= exclude) {
        /* Old number is so low that excluded numbers would wrap if we would
         * be using the 'default' way.
         * We want a random number in the range from (randomNumber + exclude + 1)
         * to maxNum:
         */
            randomNumber += (rand() % (maxNum - exclude - randomNumber)) + exclude + 1; 
        }
        else if (randomNumber > maxNum - exclude) {
        /* Old number is so high that excluded numbers would wrap if we would
         * be using the 'default' way.
         * We want a random number in the range from 1 to (randomNumber - exclude - 1):
         */
            randomNumber = (rand() % (randomNumber - exclude - 1)) + 1; 
        } else {
        /* Default way. 
         * We want a random number in the range 1 to 100, excluding numbers in the 
         * range randomNumber - exclude to randomNumber + exclude
         */
            randomNumber = ((randomNumber + (rand() % (maxNum - 2*exclude - 1) 
                    + exclude + 1) % maxNum) + 1;
        }
   }
   // do stuff
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...