2017-04-11 46 views
0
///Example 
some_array[0]:=0; 
some_array[1]:=1; 
some_array[2]:=2; 
some_array[3]:=3; 
some_array[4]:=4; 

現在我需要在陣列像這樣的(由一個單元格)移動值如何移動數組中的數據?

some_array[0]:=1; 
some_array[1]:=2; 
some_array[2]:=3; 
some_array[3]:=4; 
some_array[4]:=0; 

是否有程序的任何構建或我必須通過複製一些臨時數組手動做到這一點?

+0

沒有內置程序。您需要爲此編寫自己的代碼。 –

回答

1

這裏沒有內置功能。你將需要編寫自己的。它可能看起來像這樣:

procedure ShiftArrayLeft(var arr: array of Integer); 
var 
    i: Integer;  
    tmp: Integer; 
begin 
    if Length(arr) < 2 then 
    exit; 

    tmp := arr[0]; 
    for i := 0 to high(arr) - 1 do 
    arr[i] := arr[i + 1]; 
    arr[high(arr)] := tmp; 
end; 

請注意,沒有必要複製到臨時數組。您只需要製作一個元素的臨時副本。

如果你的數組很大,那麼複製開銷可能會很大。在這種情況下,使用圓形陣列會更好。用圓形數組記住第一個元素的索引。然後移位操作只是對該索引進行簡單的遞增或遞減操作,以數組的長度爲模。

如果您使用現代Delphi,那麼這可以很容易地轉換爲通用方法。我認爲你應該很容易地寫出相反方向的轉變。

1

RTL中沒有這樣的過程。

一個通用的方法(如提出@DavidHeffernan)可能是這個樣子:

Type 
    TMyArray = record 
    class procedure RotateLeft<T>(var a: TArray<T>); static; 
    end; 

class procedure TMyArray.RotateLeft<T>(var a: TArray<T>); 
var 
    tmp : T; 
    i : Integer; 
begin 
    if Length(a) > 1 then begin 
    tmp := a[0]; 
    for i := 1 to High(a) do 
     a[i-1] := a[i]; 
    a[High(a)] := tmp; 
    end; 
end; 

var 
    a: TArray<Integer>; 
    i:Integer;  
begin 
    SetLength(a,5); 
    for i := 0 to High(a) do a[i] := i; 
    TMyArray.RotateLeft<Integer>(a); 
    for i := 0 to High(a) do WriteLn(a[i]); 

    ReadLn; 
end. 

使用Move()低水平程序可以使用,如果性能是至關重要的:

class procedure TMyArray.RotateLeft<T>(var a: TArray<T>); 
var 
    tmp : T; 
begin 
    if Length(a) > 1 then begin 
    Move(a[0],tmp,SizeOf(T));   // Temporary store the first element 
    Move(a[1],a[0],High(a)*SizeOf(T)); 
    Move(tmp,a[High(a)],SizeOf(T)); // Put first element last 
    // Clear tmp to avoid ref count drop when tmp goes out of scope 
    FillChar(tmp,SizeOf(T),#0); 
    end; 
end; 

請注意FillChar()調用在結束時清除臨時變量。如果T是一個託管類型,它將在超出範圍時刪除最後一個數組元素的引用計數。

+0

這對任何託管類型都會失敗。您可以通過專門使用分配或專門移動來修復它。位不混合。 –

+0

@DavidHeffernan,謝謝,託管類型的引用計數必須保持。固定。 –

+0

我覺得還不夠。您需要在tmp完成之前清除tmp的內存。爲什麼不使用循環?或者,如果黑客有充分的理由,至少要解釋它。 –