Модератор: Модераторы
Procedure BList.Compare(Const aTarget: BList; Out aSame, aOver, aLack: BList);
Var
i, j: Integer;
aID, aTargetID: Integer;
Begin
If aTarget = nil Then Raise Exception.Create('Illegal nil Target');
Sort;
aTarget.Sort;
i := 0;
j := 0;
While TRUE Do
Begin
If i = Count Then aID := -1
Else aID := GetAt(i).ID;
If j = aTarget.Count Then aTargetID := -1
Else aTargetID := aTarget.GetAt(j).ID;
If (aID = -1) And (aTargetID = -1) Then Break;
If aID = aTargetID Then
Begin
aSame.Add(GetAt(i));
Inc(i);
Inc(j);
End
Else
Begin
If ((aID < aTargetID) Or (aTargetID = -1)) And Not(aID = -1) Then
Begin
aOver.Add(GetAt(i));
Inc(i)
End;
If ((aID > aTargetID) Or (aID = -1)) And Not(aTargetID = -1) Then
Begin
aLack.Add(aTarget.GetAt(j));
Inc(j);
End;
End;
End;
End;
program project2;
Uses
sysutils, Classes, BListsUnit, BObjectUnit;
Type
{ BMyClass }
BMyClass = Class(BObjectClass)
Private
Public
Destructor Burn; override;
End;
Type BMyList = Specialize BList<BMyClass>;
{ BMyClass }
Destructor BMyClass.Burn;
Begin
End;
Var
i: Integer;
aBuffer: String;
aMoment: TDateTime;
aStringList: TStringList;
aSource, aTarget, aSame, aOver, aLack: BMyList;
Begin
aSource := BMyList.Build;
aTarget := BMyList.Build;
aSame := BMyList.Build;
aOver := BMyList.Build;
aLack := BMyList.Build;
For i := 0 To 100000 Do
Begin
aSource.Add(BMyClass.Build(Random(1000000)));
aTarget.Add(BMyClass.Build(Random(1000000)));
End;
aMoment := Now;
aSource.Compare(aTarget, aSame, aOver, aLack);
WriteLn(FormatDateTime('hh:mm:ss:zz', Now - aMoment)); <- 00:00:00:243
// Проверял "вглазную" на малом кол-ве элементов - всё хорошо
// Надо бы добавить автоматизированный тест
//aStringList := TStringList.Create;
//For i := 0 To aSource.Count - 1 Do
// aStringList.Add(IntToStr(aSource[i].ID));
//aStringList.SaveToFile('aSource.txt');
//aStringList.Clear;
//
//For i := 0 To aTarget.Count - 1 Do
// aStringList.Add(IntToStr(aTarget[i].ID));
//aStringList.SaveToFile('aTarget.txt');
//aStringList.Clear;
//
//For i := 0 To aSame.Count - 1 Do
// aStringList.Add(IntToStr(aSame[i].ID));
//aStringList.SaveToFile('aSame.txt');
//aStringList.Clear;
//
//For i := 0 To aOver.Count - 1 Do
// aStringList.Add(IntToStr(aOver[i].ID));
//aStringList.SaveToFile('aOver.txt');
//aStringList.Clear;
//For i := 0 To aLack.Count - 1 Do
// aStringList.Add(IntToStr(aLack[i].ID));
//aStringList.SaveToFile('aLack.txt');
//aStringList.Clear;
//aStringList.Free;
end.
minoshi писал(а):но если не много, то отсортировать оба списка и затем проверить построчно
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 21