2012-02-23 48 views
3

在後:Copy sublist from list已經止住瞭解釋我的副本列表中的一個子表需要複製單個元素這樣做:複製動態數組塊

for iIndex2 := 0 to MyList.Last.Count-1 do 
    MySubList.Add(MyList.Last[iIndex2]); 

我已驗證的元素的副本,此方法列表中最高的要花費很多時間,一些女性也是如此。試圖用相同的條件模擬靜態數組我需要幾毫秒,一次複製數組中的所有子列表,而不是單個元素。 只是爲了更好地解釋,我有:

program Test_with_array_static; 

{$APPTYPE CONSOLE} 

{$R *.res} 

uses 
    System.SysUtils, System.Generics.Collections; 

type 
    TMyArray = array [1..10] of Integer; 
    TMyList = TList<TMyArray>; 

var 
    MyArray: TMyArray; 
    MyList: TMyList; 
    iIndex1, iIndex2: Integer; 
begin 
    try 
    { TODO -oUser -cConsole Main : Insert code here } 

    MyList := TList<TMyArray>.Create; 
    try 
     for iIndex1 := 1 to 10 do 
     begin 
     if MyList.Count <> 0 then MyArray := MyList.Last; 
     MyArray[iIndex1] := iIndex1; 
     MyList.Add(MyArray); 
     end; 

     for iIndex1 := 0 to Pred(MyList.Count) do 
     begin 
     for iIndex2 := 1 to 10 do Write(MyList[iIndex1][iIndex2]:3); 
     Writeln; 
     end; 
    finally 
     MyList.Free; 
    end; 

    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    Readln; 
end. 

所以我必須鑫卡特使用未列爲子表,但陣列等工作,但對我來說,我不一般知道有多少是在數組元素和需要動態數組。 我已經改變了代碼:

program Test_with_array_dynamic; 

{$APPTYPE CONSOLE} 

{$R *.res} 

uses 
    System.SysUtils, System.Generics.Collections; 

type 
    TMyArray = array of Integer; 
    TMyList = TList<TMyArray>; 

var 
    MyArray: TMyArray; 
    MyList: TMyList; 
    iIndex1, iIndex2: Integer; 
begin 
    try 
    { TODO -oUser -cConsole Main : Insert code here } 

    MyList := TList<TMyArray>.Create; 
    try 
     SetLength(MyArray, 10); 
     for iIndex1 := 1 to 10 do 
     begin 
     if MyList.Count <> 0 then MyArray := MyList.Last; 
     MyArray[iIndex1] := iIndex1; 
     MyList.Add(MyArray); 
     end; 

     for iIndex1 := 0 to Pred(MyList.Count) do 
     begin 
     for iIndex2 := 1 to 10 do Write(MyList[iIndex1][iIndex2]:3); 
     Writeln; 
     end; 
    finally 
     MyList.Free; 
    end; 

    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    Readln; 
end. 

等等,我再有之前的問題;當然,改變這一行:

if MyList.Count <> 0 then MyArray := MyList.Last; 
在拷貝單個元素的模式

,所有的工作。 現在我問,如果真的不可能一次複製一個數組,而沒有爲單個元素做一個副本,我只需要它的速度問題。時間非常重要。 非常感謝所有能解決我這個問題的人。再次感謝。

+0

我無法理解這一點。哪幾位代碼需要幾分鐘時間,哪一個代碼需要幾毫秒? – 2012-02-23 10:40:55

+1

大衛您好,如果我嘗試從列表中複製單個元素到其他元素,超過1000000個元素的列表(這是我的情況,關於統計信息calc),它也需要很多時間,也需要很長的時間。如果我將數組作爲列表的地方,則需要幾毫秒。在這種情況下列表的問題是隻有當我複製單個元素;除此之外,兩者的時間「相同」(在意義上非常相似)。如果你想,我試着重現它,併發布兩種情況下的代碼。只要告訴我是否需要發佈廣告回答,或者只是添加到原始文章,這是我的疑問。再次感謝。 – 2012-02-23 11:49:45

回答

3

您需要添加一個複製陣列的。否則,由於您一直將數組變量的長度設置爲相同的值,因此您最終將使用同一個動態數組。要製作一個陣列的副本,只需在將其添加到列表中之前調用Copy

MyList.Add(Copy(MyArray)); 
2

如果我理解正確的話,你要複製的內存來提高速度,下面是做這件事:

type 
    TMyArray = array of Integer; 

procedure CopyMyArraytest; 
var 
    LSrcArray: TMyArray; 
    LDestArray: TMyArray; 
    Index: Integer; 
begin 
    // set the length, can be later changed 
    SetLength(LSrcArray, 100); 
    // fill the array 
    for Index := Low(LSrcArray) to High(LSrcArray) do 
    LSrcArray[index] := index; 
    // prepare the length of destination array 
    SetLength(LDestArray, Length(LSrcArray)); 
    // copy elements from source to dest, we need Length(LSrcArray) * SizeOf(Integer) 
    // because Move needs the number of bytes, we are using "integer" so a simple 
    // multiplication will do the job 
    Move(LSrcArray[Low(LSrcArray)], LDestArray[Low(LDestArray)], Length(LSrcArray) * SizeOf(Integer)); 

    // compare elements, just to make sure everything is good 
    for Index := Low(LSrcArray) to High(LSrcArray) do 
    if LSrcArray[Index] <> LDestArray[Index] then begin 
     ShowMessage('NOOO!!!'); 
     Exit; 
    end; 
    ShowMessage('All good'); 
end; 
+0

你好,我很喜歡這個解決方案和工作;只是一個couriosity,是否可以應用MOVE不僅用於數組,而且也用於元素列表?例如在其他帖子:http://stackoverflow.com/questions/9337775/copy-sublist-from-list#comment11791540_9337775邁克W,解決了我的問題做單個元素的副本。如果可以做到這一點,因爲我可以修改該代碼,我複製單個元素與移動做到這一點?非常感謝。關於搬家,我學到了一些新東西。 – 2012-02-23 11:59:51

+0

如果我理解正確,你應該可以做到這一點,例如Move(LSrcArray [15],LDestArray [15],SizeOf(Integer)),但我不知道這與LdestArray [15]相比有多快: = LsrcArray [15];請注意,在這種情況下,我複製了第16個元素(我們從零開始),但您也可以複製LDestArray [0]:= LSrcArray [15];使用最適合你的 – ComputerSaysNo 2012-02-23 12:03:43

+0

我上面的例子複製了SizeOf(Integer),它應該是win32上的4,但不要假設它更安全,因此使用SizeOf(Integer),所以使用Move可能會提高速度,但這是你的呼叫 – ComputerSaysNo 2012-02-23 12:04:46