C#. Новичек не может сообразить, как сделать реверс массива массивов

Начал изучать С# с нуля без опыта программирования. Дошел до массивов (впереди - методы). Придумал, как сортировать и реверсить обычные массивы (одномерные, двухмерные, трехмерные и т.д.) через легкую сортировку по типу

temp = nums[i][j];
nums[i][j] = nums[k][m];
nums[k][m] = temp;

Но не могу понять, как можно осуществить реверс массива массивов через подобную конструкцию :((

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

Какой-то конкретный массив массивов, например

int[][] nums = new int[3][];
nums[0] = new int[1];
nums[1] = new int[2];
nums[2] = new int[3];

Через костыли получается сделать, но это разовое решение, которое не работает, если менять количество элементов массивов.

С сортировкой по убыванию и возрастранию массива массивов проблем нет, все работает без костылей, затык только с реверсом.

Вот пример реверса двухмерного массива (не смеяться, просто для примера, как я пытаюсь сделать)

Random random = new Random();

int[,] numbers = new int[random.Next(2,10), random.Next(2, 10)];

for (int i = 0; i < numbers.GetLength(0); i++)
{
    for (int j = 0; j < numbers.GetLength(1); j++)
    {
        numbers[i, j] = random.Next(-100, 100);
    }
}

Console.WriteLine($"2D array is: {numbers.GetLength(0)}, {numbers.GetLength(1)}");
Console.WriteLine();
Console.WriteLine("Original array is: ");

for (int i = 0; i < numbers.GetLength(0); i++)
{
    for (int j = 0; j < numbers.GetLength(1); j++)
    {
        Console.Write($"{numbers[i, j]}\t");
    }
    Console.WriteLine();
}
Console.WriteLine();

int temp = 0;
int i_mid = numbers.GetLength(0) / 2;
int j_mid = numbers.GetLength(1) / 2;                          

for (int i = 0; i < numbers.GetLength(0); i++)
{
    for (int j = 0; j < j_mid; j++)
    {
        temp = numbers[i, j];
        numbers[i, j] = numbers[numbers.GetLength(0) - (i + 1), numbers.GetLength(1) - (j + 1)];
        numbers[numbers.GetLength(0) - (i + 1), numbers.GetLength(1) - (j + 1)] = temp;
    }
    if (remainder > 0 && i < i_mid)
    {
        temp = numbers[i, j_mid];
        numbers[i, j_mid] = numbers[numbers.GetLength(0) - (i + 1), j_mid];
        numbers[numbers.GetLength(0) - (i + 1), j_mid] = temp;
    }
}
Console.WriteLine("Reversed array is: ");

for (int i = 0; i < numbers.GetLength(0); i++)
{
    for (int j = 0; j < numbers.GetLength(1); j++)
    {
        Console.Write($"{numbers[i, j]}\t");
    }
    Console.WriteLine();
}
Console.WriteLine();

И сортировка массива массивов

Random random = new Random();
int temp = 0;
int[][] nums = new int[3][];
nums[0] = new int[1];
nums[1] = new int[2];
nums[2] = new int[3];

Console.WriteLine("Original array is: ");
for (int i = 0; i < nums.Length; i++)
{
    for (int j = 0; j < nums[i].Length; j++)
    {
        nums[i][j] = random.Next(100);
    }
}

for (int i = 0; i < nums.Length; i++)
{
    for (int j = 0; j < nums[i].Length; j++)
    {
        Console.Write($"{nums[i][j]}\t");
    }
    Console.WriteLine();
}

for (int i = 0; i < nums.Length; i++)
{
    for (int j = 0; j < nums[i].Length; j++)
    {
        for (int k = 0; k < nums.Length; k++)
        {
            for (int m = 0; m < nums[k].Length; m++)
            {
                if(nums[i][j] > nums[k][m])
                {
                    temp = nums[i][j];
                    nums[i][j] = nums[k][m];
                    nums[k][m] = temp;
                }
            }
        }
    }
}
Console.WriteLine();
Console.WriteLine("Descending sorted array is: ");

for (int i = 0; i < nums.Length; i++)
{
    for (int j = 0; j < nums[i].Length; j++)
    {
        Console.Write($"{nums[i][j]}\t");
    }
    Console.WriteLine();
}

Ответы (1 шт):

Автор решения: tym32167

Для реверса, сначала напишем алгоритм для одномерного массива.

Во первых, нам понядобится функция, которая меняет 2 элемента местами

void Swap<T>(T[] data, int i, int j)
{
    (data[i], data[j]) = (data[j], data[i]);
}

Потом обычный код реверса одномерного массива, идем с концов и меняем элементы местами

void Reverse<T>(T[] array)
{
    var l = 0;
    var r = array.Length - 1;
    while (l < r) Swap(array, l++, r--);
}

Для проверки реверснем массив

int[] test1 = new[] { 1, 2, 3, 4, 5, 6 };
Console.WriteLine("test1 before reverse");
Console.WriteLine(string.Join(", ", test1));
Reverse(test1);
Console.WriteLine("test1 after reverse");
Console.WriteLine(string.Join(", ", test1));

Ввывод

test1 before reverse
1, 2, 3, 4, 5, 6
test1 after reverse
6, 5, 4, 3, 2, 1

Ну и можно заметить, что массив массивов - это такой же одномерный массив, никаких отличий. Потому можно переиспользовать код и реверснуть сначала каждый вложенный массив, потом и сам массив (хотя порядок не важен тут)

int[][] test2 = new int[][] { new int[] { 1, 2, 3 }, 
                              new int[] { 4, 5, 6 }, 
                              new int[] { 7, 8, 9 } };

Console.WriteLine("test2 before reverse");

foreach (var array in test2)
    Console.WriteLine(string.Join(", ", array));

foreach (var array in test2) Reverse(array);
Reverse(test2);

Console.WriteLine("test2 after reverse");
foreach (var array in test2)
    Console.WriteLine(string.Join(", ", array));

Вывод ожидаемо предсказуем

test2 before reverse
1, 2, 3
4, 5, 6
7, 8, 9
test2 after reverse
9, 8, 7
6, 5, 4
3, 2, 1
→ Ссылка