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 шт):
Для реверса, сначала напишем алгоритм для одномерного массива.
Во первых, нам понядобится функция, которая меняет 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