C++. Разработка класса Random генерирования случайных чисел

Разработка класса Random генерирования случайных чисел

Перед использованием данной темы рекомендуется ознакомиться с темой:


Содержание


Поиск на других ресурсах:




Условие задачи

Разработать класс Random, который содержит средства для генерирования последовательностей случайных чисел. Продемонстрировать работу класса. Программу разработать как Console Application.

 

Решение

1. Объявить внутренние переменные min, max

На первом шаге вводятся внутренние переменные. В нашем случае в раздел private нужно ввести переменные со следующими именами:

  • min – нижний предел диапазона случайных чисел;
  • max – верхний предел диапазона случайных чисел.

Внутренние переменные min, max имеют тип double. Класс поддерживает работу как с целыми числами так и с вещественными числами.

На данном этапе исходный код программы следующий:

#include <iostream>
#include <stdlib.h> // нужен для вызова функции rand(), srand()
#include <time.h> // нужен для вызова функции time()
using namespace std;

// Класс Random
class Random
{
private:
  double min, max; // Диапазон генерирования
}

 

2. Начальная инициализация. Конструкторы класса

В конструкторах помещается код установления начального значения (стартовой точки) для дальнейшего генерирования последовательностей

srand(time(NULL));

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

Текст конструкторов класса следующий

...

// Класс Random
class Random
{
private:
  double min, max; // Диапазон генерирования

public:
  // Конструкторы класса
  // Конструктор без параметров, инициализировать генератор чисел.
  // По умолчанию устанавливается диапазон [0, 100].
  Random(double min, double max)
  {
    srand(time(NULL));

    // Корректировка, если неправильно указаны пределы
    if (max > min)
    {
      this->min = max;
      this->max = min;
    }
    else
    {
      this->min = min;
      this->max = max;
    }
  }

  // Конструктор с двумя параметрами, которые устанавливают диапазон
  // генерирование случайных чисел
  Random(double min, double max)
  {
    srand(time(NULL));
    this->min = min;
    this->max = max;
  }
}

 

3. Функции, которые генерируют одиночные случайные числа

При генерировании случайных чисел базовыми методами класса являются методы генерирования одиночных случайных чисел. В классе реализовано генерирование как целых чисел, так и чисел с плавающей запятой.

3.1. Функции NextInt(). Генерирование целых чисел

Для генерирования целых чисел используются две функции, которые различаются входными параметрами. Одна из функций (с двумя параметрами) в качестве входных параметров получает минимальное и максимальное значения, которые формируют диапазон полученного числа. Другая функция (без параметров) использует значение внутренних переменных класса min, max для формирования диапазона сгенерированных чисел.

// Функция генерирования случайного целого числа в указанных границах.
// Диапазон чисел: [min, max]
int NextInt(int min, int max)
{
  // Получить случайное число - формула
  int num = min + rand() % (max - min + 1);
  return num;
}

// Функция генерирования случайного целого числа на основании
// данных текущего экземпляра.
int NextInt()
{
  return NextInt((int)this->min, (int)this->max);
}

 

3.2. Функции NextFloat(). Генерирование чисел с плавающей запятой

Для работы с числами с плавающей запятой в классе реализованы две перегруженные функции NextFloat(). Одна из функций возвращает число с плавающей запятой для диапазона значений (min, max), который задается как параметр функции. Вторая функция возвращает число с плавающей запятой для диапазона значений (min, max), который заданн во внутренних полях экземпляра класса.

Обе функции построены таким образом, что позволяют получить число с плавающей запятой с заданной точностью. Точность задается целым числом, которое равно количеству знаков после запятой.

Текст функций следующий:

// Функция, которая генерирует случайное число с плавающей запятой и заданной точностью.
// Функция получает 3 параметра:
// - min - нижняя граница;
// - max - верхняя граница;
// - precision - точность, количество знаков после запятой.
double NextFloat(double min, double max, int precision = 2)
{
  double value;

  // получить случайное число как целое число с порядком precision
  value = rand() % (int)pow(10, precision);

  // получить вещественное число
  value = min + (value / pow(10, precision )) * (max - min);

  return value;
}

// Перегруженный вариант NextFloat(), функция получает параметр - точность.
// Диапазон определяется на основании заданного экземпляра.
double NextFloat(int precision = 2)
{
  double value;
  // получить случайное число как целое число с порядком precision
  value = rand() % (int)pow(10, precision);

  // получить вещественное число
  value = min + (value / pow(10, precision)) * (max - min);

  return value;
}

 

4. Функции GetArrayInt() и GetArrayFloat(). Формирование последовательностей (массивов) чисел

Для расширения возможностей класса Random, в нем введены две дополнительные функции:

  • функция GetArrayInt() возвращает указатель на массив целых чисел, сгенерированных случайно;
  • функция GetArrayFloat() возвращает указатель на массив случайных чисел с плавающей запятой.

Функции выделяют память для результирующего массива. Эту память нужно освободить после использования в вызывающем коде.

// Метод, который возвращает массив целых чисел в диапазоне,
// который установлен значениями min, max текущего экземпляра.
// Входной параметр count - количество чисел в массиве
int* GetArrayInt(int count)
{
  int* A = new int[count];
  for (int i = 0; i < count; i++)
    A[i] = NextInt();
  return A;
}

// Метод, который возвращает массив вещественных чисел в диапазоне,
// который установлен в заданном экземпляре.
// Входные параметры:
// - count - количество чисел в массиве;
// - precision - точность (количество знаков после запятой).
double* GetArrayFloat(int count, int precision = 2)
{
  double* A = new double[count];
  for (int i = 0; i < count; i++)
    A[i] = NextFloat(precision);
  return A;
}

 

5. Функции SetMinMax(), GetMin(), GetMax(). Доступ к внутренним переменным

Иногда возникает необходимость изменить или прочитать диапазон значений, которые генерируются методами экземпляра класса Random. Для этого в классе реализованы методы доступа к переменным min, max.

// ----------- Методы доступа к внутренним переменным -------------
void SetMinMax(double min, double max)
{
  this->min = min;
  this->max = max;
}

double GetMin()
{
  return min;
}

double GetMax()
{
  return max;
}

 

6. Функция main(). Демонстрация использования класса Random

В функции main() демонстрируется использование класса Random. Текст функции следующий:

void main()
{
  // 1. Объявить экземпляры класса
  Random R1(0, 5); // вызывается конструктор с 2 параметрами
  Random R2; // вызывается конструктор без параметров

  // 2. Проверка метода NextInt()
  int d1 = R1.NextInt();
  int d2 = R1.NextInt();

  cout << "d1 = " << d1 << endl;
  cout << "d2 = " << d2 << endl;

  // 3. Демонстрация метода GetArrayInt()
  int* D = R1.GetArrayInt(20); // выделяется память для массива D

  cout << "Array D: ";
  for (int i = 0; i < 20; i++)
    cout << D[i] << " ";
  cout << endl;

  delete[] D; // не забыть освободить память

  // 4. Инициализация другим экземпляром класса
  Random R3 = R1;
  double* X = R3.GetArrayFloat(10, 4); // выделяется память

  cout << "Array X: ";
  for (int i = 0; i < 10; i++)
    cout << X[i] << " ";
  cout << endl;

  delete[] X; // освободить память

  // 5. Установить новые пределы в экземпляре R1
  R1.SetMinMax(19, 13); // числа в диапазоне [13; 19]

  // Сгенерировать новую последовательность в R1
  double* X2 = R1.GetArrayFloat(10, 3);

  cout << "Array X2:";
  for (int i = 0; i < 10; i++)
    cout << X2[i] << " ";
  cout << endl;

  delete[] X2;
}

 

7. Текст всей программы (сокращенный вариант)

В сокращенном виде текст класса Random следующий:

#include <iostream>
#include <stdlib.h> // нужен для вызова функций rand(), srand()
#include <time.h> // нужен для вызова функции time()
using namespace std;

// Класс Random
class Random
{
private:
  double min, max; // Диапазон генерирования

public:
  // ----------- Конструкторы класса ----------------------
  // Конструктор без параметров, инициализировать генератор чисел.
  // По умолчанию устанавливается диапазон [0, 100].
  Random()
  {
    ...
  }

  // Конструктор с двумя параметрами, которые устанавливают диапазон
  // генерирования случайных чисел
  Random(double min, double max)
  {
    ...
  }

  // ------ Методы генерирования одиночных случайных чисел --------
  // Функция генерирования случайного целого числа на основе
  // данных текущего экземпляра.
  int NextInt()
  {
    ...
  }

  // Функция генерирования случайного целого числа в указанных границах.
  // Диапазон чисел: [min, max]
  int NextInt(int min, int max)
  {
    ...
  }

  // Функция, которая генерирует случайное число с плавающей запятой и заданной точностью.
  // Функция получает 3 параметра:
  // - min - нижняя граница;
  // - max - верхняя граница;
  // - precision - точность, количество знаков после запятой.
  double NextFloat(double min, double max, int precision = 2)
  {
    ...
  }

  // Перегруженный вариант NextFloat(), функция получает параметр - точность.
  // Диапазон определяется на основе заданного экземпляра.
  double NextFloat(int precision = 2)
  {
    ...
  }

  // ---------- Методы генерирования последовательностей -----------------
  // Метод, который возвращает массив целых чисел в диапазоне,
  // который установлен значениями min, max текущего экземпляра.
  // Входной параметр count - количество чисел в массиве
  int* GetArrayInt(int count)
  {
    ...
  }

  // Метод, который возвращает массив вещественных чисел в диапазоне,
  // который установлен в заданном экземпляре.
  // Входные параметры:
  // - count - количество чисел в массиве;
  // - precision - точность (количество знаков после запятой).
  double* GetArrayFloat(int count, int precision = 2)
  {
    ...
  }

  // ----------- Методы доступа к внутренним переменным ----------------
  void SetMinMax(double min, double max)
  {
    ...
  }

  double GetMin()
  {
    ...
  }

  double GetMax()
  {
    ...
  }
};

void main()
{
  ...
}

 


Связанные темы