2017-04-11 18 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的内存。为什么不使用循环?或者,如果黑客有充分的理由,至少要解释它。 –