2014-07-16 43 views
0

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

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. 

回答

5

你传入High(A)到计数参数,但你应该通过Length(A)。 高返回的最高索引是比基于零的数组中的元素数少一个。

另外计算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; 
+0

传递高(A)是正确的,因为声明'SliceSize:=(面积+切片)的div片;'其实'( “真实尺寸” +切片 - 1 )div Slices'并使用High(A)有效地给出“实际大小”-1。 – Kanitatlan