2014-07-16 2 views
0

처리를 위해 여러 스레드로 보낼 수 있도록 배열 범위를 어떻게 계산할 수 있습니까? 이것은 낮은 범위에서만 가능합니다. 배열의 높은 값과 일치하지 않습니다.배열 범위를 계산하는 방법은 무엇입니까?

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)을 통과해야한다. High는 0을 기준으로 한 배열의 요소 수보다 하나 적은 가장 높은 인덱스를 반환합니다.

또한 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 조각을 사용하고 High (A)를 사용하면 효과적으로 "실제 크기"-1을 부여합니다. – Kanitatlan