【问题标题】:Sorting multidimensional array in Delphi 2007在 Delphi 2007 中对多维数组进行排序
【发布时间】:2013-01-13 16:47:44
【问题描述】:

我有一个类似于下面描述的多维数组:

Matrix => array(
 [0] => array( [0] => 7, [1] => 'hello' ),
 [1] => array( [0] => 3, [1] => 'there' ),
 [2] => array( [0] => 1, [1] => 'world' ),
)

我想要实现的是使用 Matrix[i][0] 的值对这个数组进行排序。最有效的方法是什么?我研究了递归 QuickSort 函数的可能性,但它相当复杂,因为我是多维数组。有很多快速排序的例子,但没有一个能处理将“Array of Array of String”作为输入。

如果我的文字看起来乱码,请要求澄清。我对 Delphi 还是很陌生。

【问题讨论】:

  • 您没有字符串数组。你你拥有的是Delphi无法代表的东西。您不能拥有异构数组(具有多种类型值的数组,例如整数和字符串)。您应该拥有的是一个记录数组,其中记录的第一个字段是一个整数,第二个字段是一个字符串。将其视为一个记录数组,是否更容易理解 any 排序函数应该能够同样良好地处理这些数据?顶级数组的数据类型(整数、字符串、记录、数组等)无关紧要。
  • 你能贴出你的数组声明的真实代码吗?
  • 你尝试过什么,你在哪里卡住了? QuickSort 是一个相当简单的算法,特别是如果你找到一个现成的实现来改变你自己的需要。 QuickSort 并不真正关心数组中的内容,它所需要的只是一种比较两个元素的方法以及一种在数组中移动它们的方法。忽略您的数组是多维的这一事实:您正在对一个简单的一维数组进行排序,其中数组的元素恰好也是一维数组。

标签: string delphi sorting multidimensional-array delphi-2007


【解决方案1】:

首先我质疑您是否选择了正确的类型来表示您的数据结构。你说你的类型是

array of array of string

但是看起来内部数组总是有两个元素,第一个是整数,第二个是字符串。在这种情况下,内部数组应替换为记录。

type
  TMyElement = record
    ID: Integer;
    Name: string;
  end;

  TMyArray = array of TMyElement;

现在你只有一个一维数组。我假设您对其中之一进行排序没有困难。


但是假设您确实需要一个多维数组。假设数组是参差不齐的,即不同的内部数组具有不同的长度。您仍然可以将该数组视为一维数组。像这样声明它:

  TStringArray = array of string;
  TMyArray = array of TStringArray;

现在您可以对TMyArray 进行排序,就像它是一个一维数组一样。

请注意,我需要为内部数组声明一个类型。原因是排序函数需要能够比较和交换外部数组的元素。所以你需要函数来做到这一点。你需要定义一个类型来实现它。例如,您的交换函数可能如下所示:

procedure Exchange(Index1, Index2: Integer);
var
  temp: TStringArray;
begin
  temp := MyArray[Index1];
  MyArray[Index1] := MyArray[Index2];
  MyArray[Index2] := temp;
end;

如果不定义TStringArray,这是不可能的。这是因为动态数组的赋值兼容性规则相当严格。


您可以根据需要扩展到任意多个维度:

  TString2DArray = array of TStringArray;
  TMyArray = array of TString2DArray;

同样,您可以使用标准数组排序来对TMyArray 的这个三维版本进行排序。

【讨论】:

  • 谢谢你,大卫,澄清这一点。我对这门语言还很陌生,没想到会像其他语言那样麻烦,其中很多都简单得多。当我设法解决我的问题并完成紧急申请后,我现在将进一步自我教育。
【解决方案2】:

正如 Rob 在他的评论中指出的那样,没有办法拥有一个存储整数和字符串的多维数组(不求助于变体)。

如果它真的只是一个包含整数/字符串对的数组,那么使用StringsObjects 属性将它们存储在TStringList 中会容易得多,然后使用CustomSort 对@ 进行排序987654326@值:

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes;

function MySortProc(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := Integer(List.Objects[Index1]) - Integer(List.Objects[Index2]);
end;

var
  SL: TStringList;
  i: Integer;
begin
  SL := TStringList.Create;
  try
    for i := 0 to 10 do
      SL.AddObject(Format('Item %d', [i]),  TObject(Random(i)));
    SL.CustomSort(@MySortProc);
    for i := 0 to SL.Count - 1 do
      WriteLn(Format('%d: %s', [Integer(SL.Objects[i]), SL[i]]));
    ReadLn;
  finally
    SL.Free;
  end;
end.

这会产生

【讨论】:

  • 非常感谢,肯。你的例子真的很有用,解决了我的问题。事实证明,我确实有错误的类型来保存我的数据。
猜你喜欢
  • 2010-10-13
  • 1970-01-01
  • 2017-11-09
  • 2023-03-23
  • 2013-03-11
  • 1970-01-01
  • 2011-06-19
相关资源
最近更新 更多