Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

96 lignes
3.5 KiB

  1. unit uutlAlgorithm;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils,
  6. uutlInterfaces;
  7. type
  8. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. generic TutlBinarySearch<T> = class(TObject)
  10. public type
  11. IReadOnlyIndexer = specialize IutlReadOnlyIndexer<T>;
  12. IComparer = specialize IutlComparer<T>;
  13. private
  14. class function DoSearch(
  15. constref aIndexer: IReadOnlyIndexer;
  16. constref aComparer: IComparer;
  17. const aMin: Integer;
  18. const aMax: Integer;
  19. constref aItem: T;
  20. out aIndex: Integer): Boolean;
  21. public
  22. // search aItem in aIndexer using aComparer
  23. // aIndex is the index the item was found or should be inserted
  24. // returns TRUE when found, FALSE otherwise
  25. class function Search(
  26. constref aIndexer: IReadOnlyIndexer;
  27. constref aComparer: IComparer;
  28. constref aItem: T;
  29. out aIndex: Integer): Boolean;
  30. end;
  31. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  32. function Supports(const aInstance: TObject; const aClass: TClass; out aObj): Boolean; overload;
  33. implementation
  34. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  35. //Helper////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  36. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  37. function Supports(const aInstance: TObject; const aClass: TClass; out aObj): Boolean;
  38. begin
  39. result := Assigned(aInstance) and aInstance.InheritsFrom(aClass);
  40. if result then
  41. TObject(aObj) := aInstance
  42. else
  43. TObject(aObj) := nil;
  44. end;
  45. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  46. //TutlBinarySearch//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  47. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  48. class function TutlBinarySearch.DoSearch(
  49. constref aIndexer: IReadOnlyIndexer;
  50. constref aComparer: IComparer;
  51. const aMin: Integer;
  52. const aMax: Integer;
  53. constref aItem: T;
  54. out aIndex: Integer): Boolean;
  55. var
  56. i, cmp: Integer;
  57. begin
  58. if (aMin <= aMax) then begin
  59. i := aMin + Trunc((aMax - aMin) / 2);
  60. cmp := aComparer.Compare(aItem, aIndexer.Items[i]);
  61. if (cmp = 0) then begin
  62. result := true;
  63. aIndex := i;
  64. end else if (cmp < 0) then
  65. result := DoSearch(aIndexer, aComparer, aMin, i-1, aItem, aIndex)
  66. else if (cmp > 0) then
  67. result := DoSearch(aIndexer, aComparer, i+1, aMax, aItem, aIndex);
  68. end else begin
  69. result := false;
  70. aIndex := aMin;
  71. end;
  72. end;
  73. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  74. class function TutlBinarySearch.Search(
  75. constref aIndexer: IReadOnlyIndexer;
  76. constref aComparer: IComparer;
  77. constref aItem: T;
  78. out aIndex: Integer): Boolean;
  79. begin
  80. result := DoSearch(aIndexer, aComparer, 0, aIndexer.Count-1, aItem, aIndex);
  81. end;
  82. end.