Загрузка данных


#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;
}