在Delphi中使用具有多维动态数组的Length()

时间:2008-10-02 14:52:53

标签: delphi arrays

我在delphi中使用多维动态数组,并试图解决这个问题:

对于第一个索引和第二个索引,我有两个完全独立的单独值。

当新值出现时,如果新值超出任何一个值,我想增长数组。

对于新值x,y

我检查:

if Length(List) < (x + 1) then
   SetLength(List, x + 1);
if Length(List[0]) < (y + 1) then
   SetLength(List, Length(List), y + 1);

这是正确的方法吗?还是有更好的方法来根据需要增长数组?

3 个答案:

答案 0 :(得分:4)

对我来说这很好 - 如果你将最后一行改为

SetLength(List, Length(List), y + 1);

答案 1 :(得分:2)

我想你忘了在第二个维度上使用第二个索引;

你的代码应该是这样的:

if Length(List) < (x + 1) then
   SetLength(List, x + 1);
if Length(List[x]) < (y + 1) then
   SetLength(List[x], y + 1);

注意在增长第二维时使用'x'作为第一个维度索引。

但要注意一点:

你应该意识到Delphi也在动态数组上使用引用计数(就像使用AnsiString一样)。 因此,像上面那样增长数组会起作用,但对它的任何其他引用仍然会有旧的副本!

解决这个问题的唯一方法就是用一个额外的间接级别来跟踪这些数组 - 即。 :使用指向动态数组的指针(它本身也是指针,但没关系)。

另请注意,任何这些“外部”指针都应在动态数组地址可能发生变化的任何情况下更新,如使用SetLength()进行增长/缩小时。

答案 2 :(得分:1)

<德尔> @PatrickvL: 对不起,但这是完全错误的。您的代码甚至没有编译,因为它试图为一维元素List [x]设置两个维度。 (PatrickvL更新了他的代码,因此这部分答案不再有效。)

以下代码演示了多维数组大小调整。

程序TestDimensions;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  List: array of array of integer;

begin
  //set both dimensions
  SetLength(List, 3, 2);
  Writeln('X = ', Length(List), ', Y = ', Length(List[0])); //X = 3, Y = 2
  //set main dimension to 4, keep subdimension untouched
  SetLength(List, 4);
  Writeln('X = ', Length(List), ', Y = ', Length(List[0])); //X = 4, Y = 2
  //set subdimension to 3, keep main dimenstion untouched
  SetLength(List, Length(List), 3);
  Writeln('X = ', Length(List), ', Y = ', Length(List[0])); //X = 4, Y = 3
  //all List[0]..List[3] have 3 elements
  Writeln(Length(List[0]), Length(List[1]), Length(List[2]), Length(List[3])); //3333
  //you can change subdimension for each List[] vector
  SetLength(List[0], 1);
  SetLength(List[3], 7);
  //List is now a ragged array
  Writeln(Length(List[0]), Length(List[1]), Length(List[2]), Length(List[3])); //1337
  //this does not even compile because it tries to set dimension that does not exist!
//  SetLength(List[0], Length(List[0]), 12);
  Readln;
end.

Delphi帮助也很好地解释了这一点(结构化类型,阵列)。

  

多维动态数组   要声明多维动态数组,请使用迭代数组的......结构。例如,

     

键入TMessageGrid =字符串数组的数组;
  var Msgs:TMessageGrid;

     

声明一个二维的字符串数组。要实例化此数组,请使用两个整数参数调用SetLength。例如,如果我   和J是整数值变量,

     

SetLength(消息,I,J);

     

分配I-by-J数组,Msgs [0,0]表示该数组的元素。

     

您可以创建非矩形的多维动态数组。第一步是调用SetLength,为数组的前n个维度传递参数。例如,

     

var Ints:Integer数组的数组;
  SetLength(整数,10);

     

为Ints分配十行但没有列。之后,您可以一次分配一个列(给它们不同的长度);例如

     

SetLength(Ints [2],5);

     

使Ints的第三列长整数为五。此时(即使尚未分配其他列),您可以将值分配给第三列 - 例如,Ints [2,4]:= 6.

     

以下示例使用动态数组(以及在SysUtils单元中声明的IntToStr函数)来创建字符串的三角形矩阵。

     

变种
    A:字符串数组数组;
    我,J:整数;
    开始
      SetLength(A,10);
      对于I:=低(A)到高(A)做
        开始
          SetLength(A [I],I);
          对于J:=低(A [I])到高(A [I])做
            A [I,J]:= IntToStr(I)+','+ IntToStr(J)+'';

        端;
    结束;