如何计算Array的范围?

时间:2014-07-16 11:11:42

标签: delphi delphi-xe6

如何计算数组的范围,以便将其发送到多个线程进行处理。这适用于但只适用于较低范围。它与数组的高值不匹配。

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  TRange = record
    High: Integer;
    Low: Integer;
  end;
  TRanges = Array of TRange;

procedure Split(const Size: Integer; const Slices: Integer; var Ranges: TRanges);
var
    SliceSize: Integer;
    SliceStart: Integer;
    I: Integer;
begin
    SliceSize := (Size + Slices) div Slices;
    SetLength(Ranges, Slices);
    SliceStart := 0;
    for I := 0 to Slices - 1 do
    begin
        Ranges[I].Low := SliceStart;
        SliceStart := SliceStart + SliceSize;
        if SliceStart > Size then
        SliceStart := Size;
        Ranges[I].High := SliceStart - 1;
    end;
end;

var
  A: TArray<Integer>;
  Ranges: TRanges;
begin
  SetLength(A, 71);
  Split(High(A), 7, Ranges); // split array in to seven ranges
  // 70 is missing from Ranges..
  ReadLn;
end.

1 个答案:

答案 0 :(得分:5)

您正在将High(A)传递给count参数,但您应该传递Length(A)。 High返回最高索引,该索引比基于零的数组中的元素数少一个。

SliceSize的计算也是错误的。 它必须是这样的:

procedure Split(const Size: Integer; const Slices: Integer;
  var Ranges: TRanges);
var
  SliceSize: Integer;
  SliceStart: Integer;
  LeftOver: Integer;
  I: Integer;
begin
  SliceSize := Size div Slices;
  LeftOver := Size mod Slices;
  SetLength(Ranges, Slices);
  SliceStart := 0;
  for I := 0 to Slices - 1 do
  begin
    Ranges[I].Low := SliceStart;
    SliceStart := SliceStart + SliceSize;
    if I < LeftOver then
      Inc(SliceStart);
    Ranges[I].High := SliceStart - 1;
  end;
end;