system.copy дает ссылку на array pascal

#reference #dynamic-arrays #freepascal

#ссылка #динамические массивы #freepascal

Вопрос:

Я пишу программу, которая должна решать матричные уравнения, используя правило Крамера, и у меня есть такая функция для этого:

 function solveKramers(AMatr: Matrix; BMatr: Vector): vector;
var
    detA: real;
    solvingMatrix: Matrix;
    i, j: Integer;
begin
  detA := getDet(AMatr);

  if (not (detA = 0) or not (Length(AMatr) = Length(BMatr))) then begin
    SetLength(Result, Length(BMatr));

    for i := 0 to High(BMatr) do begin

      solvingMatrix := system.copy(AMatr);

      for j := 0 to High(solvingMatrix) do begin
        solvingMatrix[j, i] := BMatr[j];
      end;

      Result[i] := getDet(solvingMatrix) / detA;

    end;
    Exit;
  end;

end;
  

Я создал matrix = array of vector и vector = array of real
И когда я пытаюсь его использовать, solvingMatrix := system.copy(AMatr); создает ссылку на AMatr вместо создания копии этой матрицы.

Комментарии:

1. Вы действительно получаете копию массива. Но это всего лишь внешний массив. Проблема здесь в том, что язык не поддерживает многомерные массивы. Это неровные массивы, в данном случае одномерный массив, элементы которого также являются одномерными массивами. Неровные массивы в Delphi — это неправильный тип данных для работы с матрицей.

2. Кстати, правило Крамера, как правило, не является хорошим алгоритмом для решения матричных уравнений в практических ситуациях.

3. @DavidHeffernan, спасибо за информацию, я использовал правило Крамера только потому, что у нас была такая задача, но спасибо за все. Кроме того, можете ли вы предложить тип, который упростил бы работу с матрицами?

4. На вашем месте я бы использовал другой язык, и мог бы. Но то, что вам действительно нужно, — это многомерный массив, которого нет в Delphi. Вы можете подделать его, используя одномерный массив, и самостоятельно обработать 2d-индексацию (j * nCol i) . Если вы просто выполняете образовательные задания, то то, что вы сделали в своем ответе, прекрасно.

Ответ №1:

Ну, я не знаю, как это работает, но я решил это, скопировав каждую строку отдельно (странно то, что я сделал аналогично в функции getDet, но она работала нормально)
Код, который я добавил, выглядит следующим образом:

 for j := 0 to High(AMatr) do begin
  solvingMatrix[j] := system.copy(AMatr[j]);
end;