Загрузка данных
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <random>
#include <algorithm>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
using namespace std;
//-------------------------------------------------
// Очистка консоли (кросс-платформенная)
//-------------------------------------------------
void clearScreen()
{
#ifdef _WIN32
system("cls");
#else
system("clear");
#endif
}
//-------------------------------------------------
// Задержка (кросс-платформенная)
//-------------------------------------------------
void sleep_ms(int milliseconds)
{
#ifdef _WIN32
Sleep(milliseconds);
#else
usleep(milliseconds * 1000);
#endif
}
//-------------------------------------------------
// Выбор генератора случайных чисел
//-------------------------------------------------
double getRandom(int mode)
{
if (mode == 1)
{
return (double)rand() / RAND_MAX;
}
else
{
static random_device rd;
static mt19937 gen(rd());
static uniform_real_distribution<> dist(0.0, 1.0);
return dist(gen);
}
}
//-------------------------------------------------
// Тест 1. Матожидание, дисперсия, СКО
//-------------------------------------------------
void statisticsTest(int mode)
{
int N;
cout << "\nВведите N: ";
cin >> N;
vector<double> numbers(N);
double sum = 0.0;
for (int i = 0; i < N; i++)
{
numbers[i] = getRandom(mode);
sum += numbers[i];
}
double mean = sum / N;
double variance = 0.0;
for (int i = 0; i < N; i++)
{
variance += pow(numbers[i] - mean, 2);
}
variance /= N;
double stddev = sqrt(variance);
cout << fixed << setprecision(6);
cout << "\nМатематическое ожидание = " << mean << endl;
cout << "Дисперсия = " << variance << endl;
cout << "Среднеквадратическое отклонение = " << stddev << endl;
}
//-------------------------------------------------
// Тест 2. Случайные точки (графика в консоли)
//-------------------------------------------------
void pointsTest(int mode)
{
int N;
cout << "\nВведите количество точек N: ";
cin >> N;
clearScreen();
// Создаем поле 60x30 символов
const int WIDTH = 60;
const int HEIGHT = 30;
vector<vector<char>> field(HEIGHT, vector<char>(WIDTH, ' '));
cout << "Генерация " << N << " случайных точек...\n\n";
// Генерируем точки
for (int i = 0; i < N; i++)
{
int x = (int)(getRandom(mode) * WIDTH);
int y = (int)(getRandom(mode) * HEIGHT);
if (field[y][x] == ' ')
field[y][x] = '*';
else if (field[y][x] == '*')
field[y][x] = '+';
// Если больше 2 точек в одной позиции, оставляем '+'
}
// Рисуем рамку и поле
cout << "+" << string(WIDTH, '-') << "+\n";
for (int y = 0; y < HEIGHT; y++)
{
cout << "|";
for (int x = 0; x < WIDTH; x++)
{
if (field[y][x] == ' ')
cout << ' ';
else
cout << field[y][x];
}
cout << "|\n";
}
cout << "+" << string(WIDTH, '-') << "+\n";
cout << "\nЛегенда: * - 1 точка, + - 2 и более точек в одной позиции\n";
cout << "Всего точек: " << N << "\n";
// Выводим координаты первых 10 точек
cout << "\nКоординаты первых 10 точек (X,Y в долях от 0 до 1):\n";
for (int i = 0; i < min(10, N); i++)
{
double x = getRandom(mode);
double y = getRandom(mode);
cout << fixed << setprecision(4) << "(" << x << ", " << y << ")\n";
}
cout << "\nНажмите Enter для продолжения...";
cin.ignore();
cin.get();
clearScreen();
}
//-------------------------------------------------
// Тест 3. Гистограмма (графика в консоли)
//-------------------------------------------------
void histogramTest(int mode)
{
int N, M;
cout << "\nВведите N: ";
cin >> N;
cout << "Введите M: ";
cin >> M;
vector<int> histogram(M, 0);
// Генерируем числа и заполняем гистограмму
for (int i = 0; i < N; i++)
{
double value = getRandom(mode);
int interval = (int)(value * M);
if (interval == M)
interval = M - 1;
histogram[interval]++;
}
clearScreen();
// Находим максимальное значение для масштабирования
int maxCount = *max_element(histogram.begin(), histogram.end());
int maxBarWidth = 50; // Максимальная ширина столбца в символах
cout << "\n========== ГИСТОГРАММА РАСПРЕДЕЛЕНИЯ ==========\n";
cout << "N = " << N << ", M = " << M << "\n\n";
// Рисуем гистограмму
for (int i = 0; i < M; i++)
{
double left = (double)i / M;
double right = (double)(i + 1) / M;
// Вычисляем длину столбца
int barLength = (maxCount > 0) ? (histogram[i] * maxBarWidth / maxCount) : 0;
// Выводим интервал
cout << fixed << setprecision(2);
cout << "[" << setw(5) << left << "; " << setw(5) << right << ") | ";
// Выводим столбец
for (int j = 0; j < barLength; j++)
cout << "█";
// Выводим количество
cout << " " << histogram[i];
// Если это максимальное значение, добавляем пометку
if (histogram[i] == maxCount && maxCount > 0)
cout << " (max)";
cout << "\n";
}
cout << "\nМасштаб: каждый символ █ = "
<< fixed << setprecision(1)
<< (double)maxCount / maxBarWidth << " значений\n";
cout << "Максимальное значение: " << maxCount << "\n";
// Дополнительная статистика
double expectedPerInterval = (double)N / M;
cout << "\nОжидаемое количество в каждом интервале: "
<< fixed << setprecision(2) << expectedPerInterval << "\n";
cout << "\nНажмите Enter для продолжения...";
cin.ignore();
cin.get();
clearScreen();
}
//-------------------------------------------------
// Тест 4. Тест серий
//-------------------------------------------------
void seriesTest(int mode)
{
int N;
cout << "\nВведите количество испытаний N: ";
cin >> N;
int currentBit;
int previousBit;
int currentLength = 1;
int maxZeroSeries = 0;
int maxOneSeries = 0;
previousBit = (getRandom(mode) < 0.5) ? 0 : 1;
for (int i = 1; i < N; i++)
{
currentBit = (getRandom(mode) < 0.5) ? 0 : 1;
if (currentBit == previousBit)
{
currentLength++;
}
else
{
if (previousBit == 0)
maxZeroSeries = max(maxZeroSeries, currentLength);
else
maxOneSeries = max(maxOneSeries, currentLength);
currentLength = 1;
}
previousBit = currentBit;
}
if (previousBit == 0)
maxZeroSeries = max(maxZeroSeries, currentLength);
else
maxOneSeries = max(maxOneSeries, currentLength);
cout << "\nМаксимальная серия нулей = " << maxZeroSeries << endl;
cout << "Максимальная серия единиц = " << maxOneSeries << endl;
// Выводим визуализацию последовательности (первые 100 символов)
cout << "\nВизуализация последовательности (первые 100 битов):\n";
for (int i = 0; i < min(100, N); i++)
{
int bit = (getRandom(mode) < 0.5) ? 0 : 1;
cout << bit;
if ((i + 1) % 50 == 0) cout << "\n";
}
cout << "\n";
}
//-------------------------------------------------
// Главное меню
//-------------------------------------------------
int main()
{
setlocale(LC_ALL, "Russian");
srand((unsigned)time(nullptr));
int generator;
int choice;
cout << "========================================\n";
cout << "Проверка качества генераторов случайных чисел\n";
cout << "========================================\n";
cout << "\nВыберите генератор:"
<< "\n1 - rand()"
<< "\n2 - mt19937 (более качественный)"
<< "\nВаш выбор: ";
cin >> generator;
do
{
cout << "\n========== МЕНЮ ==========\n";
cout << "1. Математическое ожидание, дисперсия, СКО\n";
cout << "2. Случайные точки (ASCII-графика)\n";
cout << "3. Гистограмма распределения (ASCII-графика)\n";
cout << "4. Тест серий\n";
cout << "0. Выход\n";
cout << "Ваш выбор: ";
cin >> choice;
switch (choice)
{
case 1:
statisticsTest(generator);
break;
case 2:
pointsTest(generator);
break;
case 3:
histogramTest(generator);
break;
case 4:
seriesTest(generator);
break;
case 0:
cout << "\nЗавершение программы.\n";
break;
default:
cout << "\nНеверный пункт меню!\n";
}
if (choice != 0 && choice != 2 && choice != 3)
{
cout << "\nНажмите Enter для продолжения...";
cin.ignore();
cin.get();
}
} while (choice != 0);
return 0;
}