Удаление случайной строки и столбца двухмерного массива
Программа должна удалять рандомную строку и столбец и выводить новый массив, но возникает ошибка - не могу отловить почему
using System;
class T9
{
static void Main()
{
int[,] nums = { { 1, 2, 3 }, { 4, 5, 6 } };
Console.WriteLine("Исходный массив:");
for (int i = 0; i < nums.GetLength(0); i++)
{
for (int j = 0; j < nums.GetLength(1); j++)
{
Console.Write(nums[i, j] + " ");
}
Console.WriteLine();
}
Random rnd = new Random();
int row = rnd.Next(nums.GetLength(0));
int col = rnd.Next(nums.GetLength(1));
Console.WriteLine("Удаляется {0}-я строка и {1}-й столбец", row, col);
int[,] NewNums = new int[nums.GetLength(0)-1, nums.GetLength(0)-1];
int a, b;
for (int i = 0; i < nums.GetLength(0); i++)
{
if (i < row) a = i;
else a = i - 1;
for (int j = 0; j < nums.GetLength(1); j++)
{
if (j < col) b = j;
else b = j - 1;
NewNums[a, b] = nums[i, j];
}
}
Console.WriteLine("Новый массив:");
for (int i = 0; i < NewNums.GetLength(0); i++)
{
for (int j = 0; j < NewNums.GetLength(1); j++)
{
Console.Write(NewNums[i, j] + " ");
}
Console.WriteLine();
}
Console.ReadKey();
}
}
Ответы (2 шт):
Скорее всего ошибка здесь:
int[,] NewNums = new int[nums.GetLength(0)-1, nums.GetLength(0)-1];
Второй размер должен быть от GetLength(1) а не от 0:
int[,] NewNums = new int[nums.GetLength(0)-1, nums.GetLength(1)-1];
У вас неверно построена логика удаления, но начну не с этого. Первое, что нужно сделать, чтобы не путаться в коде - это начать писать методы. Например метод вывод матрицы на экран.
private static void ShowArray(int[,] array)
{
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
Console.Write(array[i, j] + " ");
}
Console.WriteLine();
}
}
Теперь в основном коде можно будет избежать повторения одного и того же дважды. Проще код - виднее ошибки, когда они есть. Чаще используйте вынос кода в методы.
Теперь о вашей основной ошибке. Дело в том, что цикл, который занимается удалением строки и столбца у вас выполняется на 1 раз больше по вертикали и горизонтали, чем нужно, потому что вы его запускаете по размерам исходной матрицы, а не результирующей. Все что нужно сделать - это перевернуть логику итерируясь по результирующей матрице и добавлять единицу индексатору, а не вычитать.
private static int[,] DeleteCross(int[,] array, int row, int col)
{
int[,] result = new int[array.GetLength(0) - 1, array.GetLength(1) - 1];
for (int i = 0; i < result.GetLength(0); i++)
{
int a = i >= row ? i + 1 : i;
for (int j = 0; j < result.GetLength(1); j++)
{
int b = j >= col ? j + 1 : j;
result[i, j] = array[a, b];
}
}
return result;
}
Надеюсь, вы знакомы с тернарным оператором, если нет, то это краткая запись обычного if-else - почитать можно здесь.
Итоговый код выглядит так.
static void Main(string[] args)
{
int[,] nums = { { 1, 2, 3 }, { 4, 5, 6 } };
Console.WriteLine("Исходный массив:");
ShowArray(nums);
Random rnd = new Random();
int row = rnd.Next(nums.GetLength(0));
int col = rnd.Next(nums.GetLength(1));
Console.WriteLine("Удаляется {0}-я строка и {1}-й столбец", row, col);
int[,] result = DeleteCross(nums, row, col);
Console.WriteLine("Новый массив:");
ShowArray(result);
Console.ReadKey();
}
Обратите внимание, насколько проще и понятнее стал выглядеть основной код.
Вывод в консоль.
Исходный массив:
1 2 3
4 5 6
Удаляется 1-я строка и 1-й столбец
Новый массив:
1 3
Кстати, пользователю вы выводите не порядковый номер строки и столбца, а их индексы. Несмотря на то что вывод верный, люди все-таки считают строки и столбцы начиная с единицы, а не с нуля. Так что можно добавить единичку индексам, чтобы вывод был более дружелюбным человеку.