Загрузка...

Как сделать генерацию чисел ?

Тема в разделе C/C++ создана пользователем KleverAN 27 фев 2023. 258 просмотров

  1. KleverAN
    KleverAN Автор темы 27 фев 2023 3 13 янв 2020
    Вообщем, нужно сделать генерацию чисел и их запись в массив без их повторения.

    Код С++
    Код
    #include <iostream>
    #include <ctime>
    using namespace std;

    void fillArray(int arr[], int size) {

    srand(time(NULL));

    for (int i = 0; i < size; i++) {
    bool already;
    do {
    already = false;
    arr[i] = rand() % 100; //generate nums
    //check nums
    for (int j = 0; j < i; j++) {
    if (arr[j] == arr[i]) {
    already = true;
    break;
    }
    }
    } while (already);
    }
    }

    int main()
    {
    const int SIZE = 40;
    int arrA[SIZE];
    int arrB[SIZE];
    int arrC[SIZE];
    fillArray(arrA, SIZE);
    fillArray(arrB, SIZE);
    fillArray(arrC, SIZE);
    for (int i = 0; i < SIZE; i++) {
    cout << arrA[i] << " ";
    }
    cout << endl;
    for (int i = 0; i < SIZE; i++) {
    cout << arrB[i] << " ";
    }
    cout << endl;
    for (int i = 0; i < SIZE; i++) {
    cout << arrC[i] << " ";
    }

    return 0;
    }
    Дело в том, что функция генерирует так сказать одинаковые числа для разных массивов, хотя это и очевидно,
    Не подскажите как сделать разные числа для разных массивов :thinking:
    [IMG]
     
    27 фев 2023 Изменено
    1. Membro
  2. unnamed
    unnamed 27 фев 2023 In Bitcoin We Trust
    Проблема заключается в том, что вы используете один и тот же генератор случайных чисел для всех трех массивов. Это означает, что при каждом вызове функции fillArray, вы начинаете генерировать случайные числа с той же самой начальной точки.

    Чтобы получить разные числа для каждого массива, вам нужно использовать разные начальные точки для генератора случайных чисел. Вы можете сделать это, например, передавая разные значения time(NULL) в качестве аргумента функции srand для каждого вызова.

    Вот как может выглядеть измененный код fillArray, учитывающий это:
    Код
    void fillArray(int arr[], int size, int seed) {

    srand(seed);

    for (int i = 0; i < size; i++) {
    bool already;
    do {
    already = false;
    arr[i] = rand() % 100; //generate nums
    //check nums
    for (int j = 0; j < i; j++) {
    if (arr[j] == arr[i]) {
    already = true;
    break;
    }
    }
    } while (already);
    }
    }
    И затем вызывайте функцию fillArray для каждого массива, передавая разные значения time(NULL):
    Код
    const int SIZE = 40;
    int arrA[SIZE];
    int arrB[SIZE];
    int arrC[SIZE];
    fillArray(arrA, SIZE, time(NULL));
    fillArray(arrB, SIZE, time(NULL) + 1); // добавляем 1 секунду к первой начальной точке
    fillArray(arrC, SIZE, time(NULL) + 2); // добавляем 2 секунды к первой начальной точке
    Таким образом, каждый вызов fillArray будет использовать свой уникальный генератор случайных чисел, начиная с разных начальных точек, что приведет к генерации разных наборов случайных чисел для каждого массива.
     
    1. Daemon
      unnamed, Зерно генерации это называется.
  3. Silent_screams
    Silent_screams 27 фев 2023 Заблокирован(а) 0 25 фев 2023
     
  4. HaKerHD93
    HaKerHD93 27 фев 2023 57 15 окт 2018
    Вариант предоставленный unnamed хороший. но srand не очень хороший ГПСЧ (лично по моему субъективному мнению, Вы в праве пользоваться хоть srand, хоть mt19937. Как вашей душе угодно). Поэтому хочу предложу иной ГПСЧ - mt19937.
    Пример уже готового mt19937:
    Код
            std::mt19937 mt;
    std::random_device rd;
    mt.seed(rd() ^ (
    (std::mt19937::result_type)
    std::chrono::duration_cast<std::chrono::seconds>(
    std::chrono::system_clock::now().time_since_epoch()
    ).count() +
    (std::mt19937::result_type)
    std::chrono::duration_cast<std::chrono::microseconds>(
    std::chrono::high_resolution_clock::now().time_since_epoch()
    ).count()));
    std::uniform_int_distribution<int> dist(50, 200);
    int rand = dist(mt);
    p = mt() % rand;
     
    1. Посмотреть предыдущие комментарии (2)
    2. LVV
      Daemon, потому что rand работает на основе линейки (линейный конгруэнтный алгоритм), а в 11 это все апдейтнули (если не ошибаюсь) и причем тут происхождение, если имплементация не зависит от языка))
    3. Daemon
      LVV, Возможно это действительно так (просто я думал, что не особо там что то меняют, просто зачем? если это для совместимости с ANSI C сделано было, везде не рекомендуют использовать ту часть плюсов, которая к C относится), но в C++11 добавили random (и улучшили старый C'шный rand?) и почему то везде пишут, что надо его, а не rand https://stackoverflow.com/a/18726221 https://en.cppreference.com/w/cpp/numeric/random/rand
      [IMG]
      (честно разбираться не хочу, что там с rand'ом в плюсах, так что опять же не отменяю того факта, что подкрутили его, хотя можно предположить - для того, чтобы легаси код (до 11) получше работал, наверно так и есть)

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

      + нет смысла усложнять себе жизнь, когда есть готовые функции
Загрузка...
Top