Помогите оптимизировать метод
Нужно реализовать такой вот метод, он работает, но заказчик ругается на то, что FillMatrix работает неэффективно, помогите пожалуйста как-либо оптимизировать код, буду благодарен
Класс
SquareMatrix- квадратная матрица, содержащая числа типа int. Должен быть открытым и содержать следующие открытые члены:
- Конструктор от 1 параметра типа
uint matrixDimension- создаёт квадратную матрицу размераmatrixDimensionXmatrixDimension, заполненную нулями;- Метод void
FillMatrix()- заполняет по строкам элементы матрицы с консоли (начиная с верхней строки). Ввод каждой строки осуществляется до первой правильной попытки. При этом некорректными стоит считать не только строки, содержащие не числа типаint, но и строки с лишними пробелами или строки, содержащие больше/меньше элементов, чем требуется в соответствии с размерностью матрицы. При каждом некорректном вводе строки метод должен выводить сообщение:Incorrect input, expected <длина измерения матрицы> ints separated by spaces.Обратите внимание, что в случае ошибки метод НЕ должен откидывать уже корректно считанные строки;- Метод
void Print()- печатает матрицу как набор чисел, разделённых пробелами по строчкам (каждая новая строка матрицы - на отдельной строке); Свойство только для чтенияuint Size- количество элементов матрицы; Свойство только для чтенияuint DimensionLength- количество элементов в строке матрицы;- Индексатор типа
int, принимающий 2 параметра типаintс именамиxиy- возвращает элемент матрицы со строкой с номером x и столбцом с номером y (при чтении) или присваивает значение по указанным индексам (при записи). Проверки границ осуществлять не требуется;- Метод
bool TrySum(SquareMatrix other, out SquareMatrix result)- складывает матрицы одинакового размера и сохраняет результат в result, если матрицы действительно имеют одинаковую длину измерения, возвращая true. В противном случае метод кладёт в result значение null и возвращает false;- Метод
bool TrySubtract(SquareMatrix other, out SquareMatrix result)- выполняет вычитание матриц одинакового размера и сохраняет результат вresult, если матрицы действительно имеют одинаковую длину измерения, возвращаяtrue. В противном случае метод кладёт вresultзначениеnullи возвращает false;- Метод
SquareMatrix Multiply(int value)- выполняет умножение всех элементов матрицы на переданное число, возвращает результат в виде новой матрицы того же размера;- Метод
bool TryMatrixMultiply(SquareMatrix other, out SquareMatrix result)- выполняет матричное умножение матриц одинакового размера и сохраняет результат вresult, если матрицы действительно имеют одинаковую длину измерения, возвращаяtrue. В противном случае метод кладёт вresultзначениеnullи возвращаетfalse;- Метод
SquareMatrix Transpose()- возвращает транспонированную копию данной матрицы;
class SquareMatrix
{
int[,] Matrix;
public int this[int x, int y]
{
get => Matrix[x, y];
set => Matrix[x, y] = value;
}
private uint size;
private uint dimensionLength;
public SquareMatrix(uint matrixDimension)
{
Matrix = new int[matrixDimension, matrixDimension];
size = (uint)Matrix.Length;
dimensionLength = (uint)Matrix.GetLength(0);
}
public uint Size
{
get { return size; }
private set { }
}
public uint DimensionLength
{
get
{
return dimensionLength;
}
private set { }
}
public void FillMatrix()
{
for (int i = 0; i < Matrix.GetLength(0); i++)
{
string StrMatrixLine = Console.ReadLine();
if (FillChecker(StrMatrixLine))
{
int[] IntMatrixLine = StrMatrixLine.Split().Select(int.Parse).ToArray();
for (uint ii = 0; ii < Matrix.GetLength(0); ii++)
{
Matrix[i, ii] = IntMatrixLine[ii];
}
}
else
{
Console.WriteLine($"Incorrect input, expected {Matrix.GetLength(0)} ints separated by spaces.");
--i;
}
}
}
bool FillChecker(string StrMatrixLine)
{
if (
(Matrix.GetLength(0) - 1) == StrMatrixLine.Count(Char.IsWhiteSpace))
{
string[] MatrixLineChecker = StrMatrixLine.Split();
for (int i = 0; i < MatrixLineChecker.Length; i++)
{
if (!int.TryParse(MatrixLineChecker[i],out int IntMatrixLine))
{
return false;
}
}
return true;
}
else
{
return false;
}
}
public void Print()
{
for (uint i = 0; i < Matrix.GetLength(0); i++)
{
for (uint ii = 0; ii < Matrix.GetLength(1); ii++)
{
Console.Write($"{Matrix[i, ii]} ");
}
Console.WriteLine();
}
}
public bool TrySum(SquareMatrix other, out SquareMatrix result)
{
if (Matrix.GetLength(0) == other.Matrix.GetLength(0))
{
result = new SquareMatrix((uint)Matrix.GetLength(0));
for (int i = 0; i < Matrix.GetLength(0); i++)
{
for (int ii = 0; ii < Matrix.GetLength(0); ii++)
{
other.Matrix[i, ii] += Matrix[i, ii];
}
}
result.Matrix= other.Matrix;
return true;
}
else
{
result = null;
return false;
}
}
public bool TrySubtract(SquareMatrix other, out SquareMatrix result)
{
if (Matrix.GetLength(0) == other.Matrix.GetLength(0))
{
result = new SquareMatrix((uint)Matrix.GetLength(0));
for (int i = 0; i < Matrix.GetLength(0); i++)
{
for (int ii = 0; ii < Matrix.GetLength(0); ii++)
{
result.Matrix[i,ii]=other.Matrix[i, ii] - Matrix[i, ii];
}
}
return true;
}
else
{
result = null;
return false;
}
}
public SquareMatrix Multiply(int value)
{
SquareMatrix result = new SquareMatrix((uint)Matrix.GetLength(0));
for (int i = 0; i < Matrix.GetLength(0); i++)
{
for (int ii = 0; ii < Matrix.GetLength(0); ii++)
{
result.Matrix[i, ii]= Matrix[i, ii]*value;
}
}
return result;
}
public bool TryMatrixMultiply(SquareMatrix other, out SquareMatrix result)
{
if (Matrix.GetLength(0) == other.Matrix.GetLength(0))
{
result = new SquareMatrix((uint)Matrix.GetLength(0));
for (int i = 0; i < Matrix.GetLength(0); i++)
{
for (int ii = 0; ii < other.Matrix.GetLength(1); ii++)
{
for (int j = 0; j < other.Matrix.GetLength(0); j++)
{
result.Matrix[i, ii] += Matrix[i, j] * other.Matrix[j, ii];
}
}
}
return true;
}
else
{
result = null;
return false;
}
}
public SquareMatrix Transpose()
{
SquareMatrix result = new SquareMatrix((uint)Matrix.GetLength(0));
for (int i = 0; i < Matrix.GetLength(0); i++)
{
for (int ii = 0; ii < Matrix.GetLength(0); ii++)
{
result.Matrix[i, ii] = Matrix[ii, i];
}
}
return result;
}
}
Ответы (1 шт):
Автор решения: aepot
→ Ссылка
Кода много, весь смотреть не буду. Касательно метода, вот решение, а ниже расскажу, что к чему.
private void ThrowInvalidInput(int expectedLength)
=> throw new FormatException($"Incorrect input, expected {expectedLength} ints separated by spaces.");
public void FillMatrix()
{
int size = _matrix.GetLength(0);
for (int i = 0; i < size; i++)
{
Console.Write($"matrix[{i}]: ");
string[] tokens = Console.ReadLine().Split();
try
{
if (tokens.Length != size)
ThrowInvalidInput(size);
for (int j = 0; j < size; j++)
{
if (int.TryParse(tokens[j], out int number))
_matrix[i, j] = number;
else
ThrowInvalidInput(size);
}
}
catch (FormatException ex)
{
Console.WriteLine(ex.Message);
--i;
}
}
}
- Называйте переменные проще и понятнее, но старайтесь не использовать сокращения. Весь успех именования переменных, классов и методов заключается в том, насколько легко другим разработчиками читать ваш код.
- Чтобы не бодаться с переходами, прерванием циклов и прочим, проще всего бросать исключение. Я бы, честно говоря, выдавал бы более подробные сообщения об ошибках, но ТЗ есть ТЗ.
- Много лишних телодвижений, зачем-то прикрутили Linq. Да, красиво, но как вы словите ошибку количества элементов не распарсив все что можно в числа? К тому же в вашем коде легко может возникнуть исключение при вводе какого-нибудь
ыыыв консоль, и приложение упадет, а это несоответствует ТЗ. Ловите ошибки поэтапно, сначала длину, потом парсить числа, некуда спешить. - Чтобы не дергать один и тот же метод
GetLength(0), его результат можно закешировать локально в переменную, он же всегда одно и то же возвращает во время выполнения метода, верно? - Немного интерактивность, чтобы пользователь вообще понимал, что происходит -
Console.Write($"matrix[{i}]: ");. Желательно пользователю до начала метода сообщить, сколько ему вводить то вообще надо. Допишите это под себя.