Advertisement
WarPie90

Fast remove duplicates

Oct 12th, 2014
500
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 2.86 KB | None | 0 0
  1. program RemoveDupes;
  2.  
  3. (*
  4.   Removes duplicates while keeping the order of the array
  5.   Can be modified to fit other datatypes.
  6. *)
  7. procedure FastRemoveDupes(var Arr:TIntegerArray);
  8. var
  9.   n,l,i,j,c:Int32;
  10.   hash: UInt32;
  11.   table: Array of TIntegerArray;
  12.   Isset:Boolean;
  13. begin
  14.   n := Length(Arr);
  15.   SetLength(Table, Trunc(Pow(2, Floor(Logn(2,n)) + 1)));
  16.   c := 0;
  17.   for i:=0 to n-1 do
  18.   begin
  19.     Isset := False;
  20.     hash := Arr[i] and High(Table);
  21.     l := Length(Table[hash]);
  22.     for j:=0 to l-1 do
  23.       if (Table[hash][j] = Arr[i]) then
  24.       begin
  25.         Isset := True;
  26.         Break;
  27.       end;
  28.     if not(Isset) then
  29.     begin
  30.       SetLength(Table[hash], l+1);
  31.       Table[hash][l] := Arr[i];
  32.       Arr[c] := Arr[i];
  33.       Inc(c);
  34.     end;
  35.   end;
  36.   SetLength(Arr, c);
  37. end;
  38.  
  39.  
  40. (*
  41.   TBoxArray example version
  42. *)
  43. procedure FastRemoveDupes_TBoxArray(var Arr:TBoxArray);
  44. var
  45.   n,l,i,j,c:Int32;
  46.   hash,h1,h2: UInt32;
  47.   table: Array of TBoxArray;
  48.   Isset:Boolean;
  49. begin
  50.   n := Length(Arr);
  51.   if n <= 1 then Exit();
  52.   SetLength(Table, Trunc(Pow(2, Floor(Logn(2,n)) + 1)));
  53.   for i:=0 to n-1 do
  54.   begin
  55.     Isset := False;
  56.     h1 := UInt32((Arr[i].y1 * $0f0f1f1f) xor Arr[i].x1);
  57.     h2 := UInt32((Arr[i].y2 * $0f0f1f1f) xor Arr[i].x2);
  58.     hash := ((h1 * $0f0f1f1f) xor h2) and High(Table);
  59.  
  60.     l := Length(Table[hash]);
  61.     for j:=0 to l-1 do
  62.       if (Table[hash][j].x1 = Arr[i].x1) and (Table[hash][j].y1 = Arr[i].y1) and
  63.          (Table[hash][j].x2 = Arr[i].x2) and (Table[hash][j].y2 = Arr[i].y2) then
  64.       begin
  65.         Isset := True;
  66.         Break;
  67.       end;
  68.     if not(Isset) then
  69.     begin
  70.       SetLength(Table[hash], l+1);
  71.       Table[hash][l] := Arr[i];
  72.       Arr[c] := Arr[i];
  73.       Inc(c);
  74.     end;
  75.   end;
  76.   SetLength(Arr, c);
  77. end;
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84. //----------------------------------------------------------------------------\\
  85. //---| Benchmark and test code |----------------------------------------------\\
  86. function RandomTIA(n:Int32; Low,Hi:Int32): TIntegerArray;
  87. var i:Int32;
  88. begin
  89.   SetLength(Result, n);
  90.   for i:=0 to n-1 do
  91.     Result[i] := RandomRange(Low,Hi);
  92. end;
  93.  
  94.  
  95.  
  96. var
  97.   Arr, Out1, Out2:TIntegerArray;
  98.   t:UInt32;
  99. begin
  100.   WriteLn('---| Benchmark |-------------------------');
  101.   Arr := RandomTIA(100000,0,$FFFFFF);
  102.   Out1 := Copy(Arr);
  103.   t := GetTimeRunning();
  104.   FastRemoveDupes(Out1);
  105.   WriteLn('| FastRemoveDupes (interpreted): ', GetTimeRunning() - t,'ms');
  106.  
  107.   Out2 := Copy(Arr);
  108.   t := GetTimeRunning();
  109.   ClearSameIntegers(Out2);
  110.   WriteLn('| ClearSameIntegers (compiled):  ', GetTimeRunning() - t,'ms');
  111.  
  112.   //verify same length
  113.   WriteLn('| Same length: ', Length(Out2) = Length(Out1));
  114.  
  115.  
  116.   //test
  117.   WriteLn('---| Test |------------------------------');
  118.   Arr := [1,5,7,4,7,8,3,6,1,8,6,2,3,5,8,9,6,3,2,3,7];
  119.   WriteLn('| ',Arr);
  120.  
  121.   FastRemoveDupes(Arr);
  122.   WriteLn('| ',Arr);
  123. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement