如何交换二维数组的两行,为什么它会工作?

时间:2011-03-18 10:58:46

标签: arrays delphi row swap

综述

请查看David,Uwe和其他专家的以下评论。

=============================================== =================================

以下代码在二维动态的double值数组中交换两行。我想知道:(1)以下代码是否是交换两行二维数组的最佳实践?如果没有,那么做这种工作的最佳做​​法是什么? (2)为什么以下代码有效?我的意思是,二维数组不是一个连续连续的内存部分吗?以下代码是否仅适用于运气?任何建议表示赞赏!

    unit Unit5;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;

    type
      TAADouble = array of array of Double;

      TForm5 = class(TForm)
        procedure FormShow(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;

    var
      Form5: TForm5;

    procedure SwapRows(arr: TAADouble; row0, row1: Integer);

    implementation

    {$R *.dfm}

    procedure SwapRows(arr: TAADouble; row0, row1: Integer);
    var
      Tmp: Integer;
    begin
      {$IFDEF FPC}
      Tmp := PtrUInt(arr[row0]);
      PtrUInt(arr[row0]) := PtrUInt(arr[row1]);
      PtrUInt(arr[row1]) := Tmp;
      {$ELSE}
      Tmp := Integer(arr[row0]);
      Integer(arr[row0]) := Integer(arr[row1]);
      Integer(arr[row1]) := Tmp;
      {$ENDIF}

    end;

    procedure TForm5.FormShow(Sender: TObject);
    var
      tmpArray: TAADouble;
      I, J: Integer;
      rowStr: string;
    begin
      SetLength(tmpArray, 10, 10);
      rowStr := '';

      for I := 0 to 9 do
        for J := 0 to 9 do
          tmpArray[I][J] := I * J;

      for I := 0 to 9 do
      begin
        rowStr := '';
        for J := 0 to 9 do
          rowStr := rowStr + FloatToStr(tmpArray[I][J]) + '  ';
        OutputDebugString(PWideChar(rowStr));
      end;

      SwapRows(tmpArray, 3, 4);

      for I := 0 to 9 do
      begin
        rowStr := '';
        for J := 0 to 9 do
          rowStr := rowStr + FloatToStr(tmpArray[I][J]) + '  ';
        OutputDebugString(PWideChar(rowStr));
      end;
    end;

    end.

2 个答案:

答案 0 :(得分:4)

你问:

  

以下代码是否仅适用于   运气?

嗯,是的,您依赖于具体实施细节。

事实上,正确的写作方式非常自然而简单:

type
  TDoubleArray = array of Double;
  TDoubleMatrix = array of TDoubleArray;

procedure SwapRows(M: TDoubleMatrix; Row1, Row2: Integer);
var
  Temp: TDoubleArray;
begin
  Temp := M[Row1];
  M[Row1] := M[Row2];
  M[Row2] := Temp;
end;

您需要为行TDoubleArray声明一个中间类型,以便您可以在交换例程中执行Temp的赋值。

2D恒定大小数组

array [1..M] of array [1..N] of TMyType

是一个连续的内存块。

您所拥有的2D动态大小数组不是。实际上,在行具有不同数量的列的意义上它甚至可能是粗糙的。所以你可以有一个三角矩阵。

答案 1 :(得分:4)

动态数组实现为指向表示该数组的内存块的指针。因此,二维动态数组实际上是指向指针数组的指针。这就是为什么交换行(-pointer)实际上有效。

请参阅David的答案以获得更清洁的方法。

<强>更新 如果您被允许使用泛型,您可以这样做:

procedure <SomeClassOrRecord>.SwapRows<T>(var arr: TArray<T>; row0, row1: Integer);
var
  Tmp: T;
begin
  Tmp := arr[row0];
  arr[row0] := arr[row1];
  arr[row1] := Tmp;
end;