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


Отлично! Теперь перед нами полный текст методического материала со всеми подсказками и рекомендуемыми структурами данных.
Опираясь на этот справочный материал, я обновил и максимально адаптировал решения некоторых заданий, чтобы они строго соответствовали требованиям преподавателя (например, считывание одномерного массива поэлементно, использование TryGetValue в словаре и правильный вывод матриц/строк через предложенные вам конструкции).
Вот эталонные решения для всех 8 заданий вашей лабораторной работы.

Задание 1: Инвертирование одномерного массива

Используется построчное считывание размера, заполнение в цикле и классический алгоритм разворота через temp.
csharp
using System;

class Program
{
    static void Main()
    {
        // 1. Считывание массива чисел из консоли (по методичке)
        Console.WriteLine("Введите количество элементов массива:");
        int n = int.Parse(Console.ReadLine());
        int[] m = new int[n];
        
        for (int i = 0; i < n; i++)
        {
            Console.WriteLine("Введите элемент {0}:", i + 1);
            m[i] = int.Parse(Console.ReadLine());
        }

        // Вывод исходного массива на экран перед изменением
        Console.Write("Исходный массив: ");
        for (int i = 0; i < m.Length; i++)
        {
            Console.Write("{0} ", m[i]);
        }
        Console.WriteLine();

        // 2. Алгоритм инвертирования (разворота) массива
        int temp;
        for (int i = 0; i < m.Length / 2; i++)
        {
            temp = m[i];                          // временно сохраняем значение с начала
            m[i] = m[m.Length - 1 - i];           // записываем значение с конца
            m[m.Length - 1 - i] = temp;           // записываем сохраненное значение
        }

        // Вывод инвертированного массива
        Console.Write("Инвертированный массив: ");
        for (int i = 0; i < m.Length; i++)
        {
            Console.Write("{0} ", m[i]);
        }
        Console.WriteLine();
    }
}
Используйте код с осторожностью.

Задание 2: Заполнение двумерного массива «змейкой»

Размерность М и N задана в коде, заполнение от 1 до M*N с помощью условий if/else для управления направлением.
csharp
using System;

class Program
{
    static void Main()
    {
        int rows = 3; // Переменная M из условия
        int cols = 3; // Переменная N из условия
        int[,] matrix = new int[rows, cols];
        
        int currentNumber = 1;

        for (int i = 0; i < rows; i++)
        {
            // if, else используются для управления направлением движения змейки
            if (i % 2 == 0)
            {
                // Четная строка: идем слева направо (от 0 до cols - 1)
                for (int j = 0; j < cols; j++)
                {
                    matrix[i, j] = currentNumber++;
                }
            }
            else
            {
                // Нечетная строка: змейка разворачивается справа налево (от cols - 1 до 0)
                for (int j = cols - 1; j >= 0; j--)
                {
                    matrix[i, j] = currentNumber++;
                }
            }
        }

        // Вывод матрицы в консоль (по методичке)
        Console.WriteLine("Матрица:");
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                Console.Write(matrix[i, j] + " ");
            }
            Console.WriteLine();
        }
    }
}
Используйте код с осторожностью.

Задание 3: Копирование одномерного массива в двумерный построчно

Элементы одномерного массива последовательно переносятся в матрицу размерностью MxN.
csharp
using System;

class Program
{
    static void Main()
    {
        int rows = 3;
        int cols = 3;
        
        // Входной одномерный массив размерностью M*N (задан в коде)
        int[] sourceArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        int[,] matrix = new int[rows, cols];

        // Построчное копирование с использованием дополнительного индекса
        int sourceIndex = 0;
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                matrix[i, j] = sourceArray[sourceIndex++];
            }
        }

        // Вывод одномерного массива
        Console.Write("Исходный одномерный массив: ");
        for (int i = 0; i < sourceArray.Length; i++)
        {
            Console.Write("{0} ", sourceArray[i]);
        }
        Console.WriteLine("\n");

        // Вывод полученной матрицы в консоль
        Console.WriteLine("Двумерный массив (матрица):");
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                Console.Write(matrix[i, j] + " ");
            }
            Console.WriteLine();
        }
    }
}
Используйте код с осторожностью.

Задание 4: Поиск минимального и максимального элементов

Заполнение матрицы случайными числами через класс Random и поиск экстремумов.
csharp
using System;

class Program
{
    static void Main()
    {
        int rows = 3;
        int cols = 3;
        int[,] matrix = new int[rows, cols];

        // Используем класс Random для заполнения
        Random rnd = new Random();

        Console.WriteLine("Сгенерированная матрица:");
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                matrix[i, j] = rnd.Next(1, 100); // случайные числа от 1 до 99
                Console.Write(matrix[i, j] + " ");
            }
            Console.WriteLine();
        }

        // Алгоритм поиска MAX и MIN
        int min = matrix[0, 0];
        int max = matrix[0, 0];

        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                if (matrix[i, j] < min) min = matrix[i, j];
                if (matrix[i, j] > max) max = matrix[i, j];
            }
        }

        Console.WriteLine($"\nВыход: MIN = {min}, MAX = {max}");
    }
}
Используйте код с осторожностью.

Задание 5: Подсчет количества разных символов в строке

Используется цикл foreach для перебора символов введенной строки и коллекция для определения уникальности.
csharp
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Console.WriteLine("Введите строку символов:");
        string str = Console.ReadLine();

        // Коллекция HashSet хранит только уникальные элементы
        HashSet<char> uniqueChars = new HashSet<char>();

        // Цикл foreach используется для итерации по символам в строке
        foreach (char c in str)
        {
            uniqueChars.Add(c); 
        }

        Console.WriteLine($"Вход: \"{str}\"");
        Console.WriteLine($"Выход: Symbols = {uniqueChars.Count};");
    }
}
Используйте код с осторожностью.

Задание 6: Подсчет повторений для каждого символа

Используется строго указанный в методичке компактный подход с методом TryGetValue.
csharp
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Console.WriteLine("Введите строку символов:");
        string str = Console.ReadLine();

        // Объявление словаря, где ключ — символ (char), а значение — число повторений (int)
        Dictionary<char, int> counts = new Dictionary<char, int>();

        // Перебор символов в верхнем регистре (чтобы 'м' и 'М' считались одинаково, как в примере)
        foreach (char c in str)
        {
            char upperC = char.ToUpper(c);

            // Пытаемся получить текущее значение по ключу upperC через TryGetValue
            if (counts.TryGetValue(upperC, out int value))
            {
                counts[upperC] = value + 1; // если ключ найден — увеличиваем значение
            }
            else
            {
                counts[upperC] = 1; // если ключа не было — заводим новый со значением 1
            }
        }

        Console.WriteLine($"Вход: \"{str}\"");
        Console.Write("Выход: ");

        // Перебор всех пар «ключ — значение» словаря через KeyValuePair
        bool first = true;
        foreach (KeyValuePair<char, int> pair in counts)
        {
            if (pair.Key == ' ') continue; // Пропускаем пробелы, если нужно как в примере

            if (!first) Console.Write(", ");
            Console.Write("{0} = {1}", pair.Key, pair.Value);
            first = false;
        }
        Console.WriteLine(";");
    }
}
Используйте код с осторожностью.

Задание 7: Удаление символа из строки без готовых функций

Алгоритм построения новой строки через фильтрацию символов в цикле (на основе примера из методички).
csharp
using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Введите исходную строку:");
        string str = Console.ReadLine();

        Console.WriteLine("Введите символ для удаления:");
        char target = Console.ReadKey().KeyChar;
        Console.WriteLine(); // перевод строки после ввода символа

        string result = ""; // результирующая пустая строка

        // Реализация алгоритма из методички
        for (int i = 0; i < str.Length; i++)
        {
            if (str[i] != target) // если текущий символ не совпадает с удаляемым
            {
                result += str[i]; // копируем его в результирующую строку
            }
        }

        Console.WriteLine($"Вход: \"{str}\", \"{target}\"");
        Console.WriteLine($"Выход: \"{result}\"");
    }
}
Используйте код с осторожностью.

Задание 8: Замер времени обхода матрицы (Строки против Столбцов)

Используется класс Stopwatch для замера двух изолированных проходов по одной матрице.
csharp
using System;
using System.Diagnostics; // Необходимо для Stopwatch

class Program
{
    static void Main()
    {
        int N = 4000; // Выбрано число в диапазоне 2500 - 10000
        int[,] matrix = new int[N, N];
        long dummySum = 0; // Переменная для исключения оптимизаций компилятора

        Stopwatch sw = new Stopwatch();

        // --- Тест 1: Обход по СТРОКАМ (внешний i, внутренний j) ---
        sw.Start();
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                dummySum += matrix[i, j];
            }
        }
        sw.Stop();
        long rowTime = sw.ElapsedMilliseconds;
        Console.WriteLine("Время выполнения (по строкам): {0} мс", rowTime);

        // Сброс счетчика времени перед вторым тестом
        sw.Reset();
        dummySum = 0;

        // --- Тест 2: Обход по СТОЛБЦАМ (внешний j, внутренний i) ---
        sw.Start();
        for (int j = 0; j < N; j++)
        {
            for (int i = 0; i < N; i++)
            {
                dummySum += matrix[i, j];
            }
        }
        sw.Stop();
        long colTime = sw.ElapsedMilliseconds;
        Console.WriteLine("Время выполнения (по столбцам): {0} мс", colTime);
    }
}
Используйте код с осторожностью.

Ответы на контрольные вопросы:

1. Какой вариант цикла быстрее проходит по всему циклу?
Обход по строкам выполняется значительно быстрее. В языке C# двумерные массивы ([,]) хранятся в оперативной памяти последовательно — строка за строкой. Когда мы идем по строкам, процессор считывает данные из соседних ячеек памяти подряд и эффективно использует кэш-память процессора (кэш-линии). При обходе по столбцам происходят «прыжки» в памяти через целые строки, из-за чего возникают промахи кэша (cache misses) и процессору приходится постоянно ждать подгрузки данных из медленной оперативной памяти.
2. Меняется ли общее количество итераций цикла?
Нет, общее количество итераций не меняется. В обоих случаях внутреннее тело цикла выполняется ровно \(N \times N\) раз (например, при \(N = 4000\) это ровно \(16\,000\,000\) операций). Разница во времени обусловлена только тем, в каком порядке эти ячейки запрашиваются из оперативной памяти.
Если у вас возникнут вопросы по работе с Visual Studio или по запуску кода, дайте знать — я помогу!