Почему rand каждый раз дает мне почти одинаковые (но немного разные) числа - PullRequest
0 голосов
/ 11 февраля 2020

Я написал следующий фрагмент кода для генерации случайных чисел в c ++

#include <stdlib.h>
#include <iostream>
#include <ctime>

#define ARRAY_SIZE 5
#define MAX_VAL ARRAY_SIZE*5+1

int main() {
  srand(time(NULL));

  int arr [ARRAY_SIZE];
  for (int i = 0; i < ARRAY_SIZE; i++) {
    arr[i] = (rand() % MAX_VAL);
  }

  for (int i = 0; i < ARRAY_SIZE; i++) {
    printf ("%d\n", arr[i]);
  }

  return 0;
}

Когда я запускаю это, я получаю почти идентичных чисел каждый раз:

tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
11
16
16
21
16
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
21
11
21
11
6
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
6
6
1
16
6
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
16
1
16
6
21
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
1
21
21
11
21
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
1
21
21
11
21
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
11
16
1
1
11
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
11
16
1
1
11
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
21
1
6
6
1

Почему мой генератор случайных чисел дает мне только значения: 1, 6, 11, 16 и 21? Это не имеет смысла для меня. Я удостоверился, что засев, и числа не всегда в одном и том же порядке, что делает это еще более запутанным. В качестве примечания я использую OSX.

Ответы [ 3 ]

7 голосов
/ 11 февраля 2020

Проблема в том, что MAX_VAL определяется как ARRAY_SIZE*5+1, а не (ARRAY_SIZE*5+1). Это означает, что ваше использование в arr[i] = (rand() % MAX_VAL); расширяется до:

arr[i] = (rand() % 5 * 5 + 1);

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

const unsigned int MAX_VAL = ARRAY_SIZE * 5 + 1;

Еще одной проблемой является использование srand(time(NULL)). В большинстве систем time вернет одно и то же значение, если программа будет запущена в ту же секунду. Это означает, что запуск программы в быстрой последовательности (в течение одной секунды) даст те же результаты. Предпочтительно использовать средства PRNG в <random>.

1 голос
/ 11 февраля 2020

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

Версия этого кода на C ++ позволяет обойти многие проблемы, используя возможности C ++ и C:

#include <random>
#include <vector>
#include <iostream>

int main() {
  // Define constants instead of using #define, as this avoids interpolation syntax issues
  const size_t array_size = 5;
  const int max = array_size * 5 + 1;

  // Use the C++ random number generator facilities
  std::random_device rd;
  std::mt19937 gen(rd());
  std::uniform_int_distribution<> dis(0, max);

  // Use a dynamically sized array
  std::vector<int> arr;

  for (int i = 0; i < array_size; ++i) {
    arr.push_back(dis(gen));
  }

  // Use C++ container iteration to simplify code
  for (const int& i : arr) {
    // Use streams for output
    std::cout << i << std::endl;
  }

  return 0;
}
1 голос
/ 11 февраля 2020

Это из-за того, что вы используете #define MAX_VAL

Фактический расчет равен rand() % 5 * 5 + 1, что означает, что вы сначала делаете результат rand () на 5, а затем умножаете на 5, а затем добавляете 1.

Я предполагаю, что вы хотите написать rand () % (5 * 5 + 1) Это может быть решено с помощью:

#define MAX_VAL (ARRAY_SIZE * 5 + 1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...