trie.pas 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. { Simple TRIE implementation.
  2. Copyright (c) 2012 by Inoussa OUEDRAOGO
  3. The source code is distributed under the Library GNU
  4. General Public License with the following modification:
  5. - object files and libraries linked into an application may be
  6. distributed without source code.
  7. If you didn't receive a copy of the file COPYING, contact:
  8. Free Software Foundation
  9. 675 Mass Ave
  10. Cambridge, MA 02139
  11. USA
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. }
  15. unit trie;
  16. {$mode objfpc}{$H+}
  17. interface
  18. uses
  19. SysUtils;
  20. const
  21. MAX_CHILD_COUNT = 256;
  22. type
  23. TKeyType = Cardinal;
  24. TDataType = Integer;
  25. PTrieNode = ^TTrieNode;
  26. TTrieNode = packed record
  27. Key : TKeyType;
  28. DataNode : Boolean;
  29. Data : TDataType;
  30. ChildCount : Byte;
  31. Children : array[0..(MAX_CHILD_COUNT-1)] of PTrieNode;
  32. end;
  33. function CreateNode(
  34. const AKey : TKeyType;
  35. const AData : TDataType
  36. ) : PTrieNode; overload;
  37. function CreateNode(const AKey : TKeyType) : PTrieNode;overload;
  38. procedure FreeNode(ANode : PTrieNode);
  39. function InsertWord(
  40. const ARoot : PTrieNode;
  41. const AWord : array of TKeyType;
  42. const AValue : TDataType
  43. ) : Boolean;overload;
  44. function InsertWord(
  45. const ARoot : PTrieNode;
  46. const AWord : TKeyType;
  47. const AValue : TDataType
  48. ) : Boolean;overload;
  49. implementation
  50. function CreateNode(
  51. const AKey : TKeyType;
  52. const AData : TDataType
  53. ) : PTrieNode;
  54. begin
  55. New(Result);
  56. Result^.Key := AKey;
  57. Result^.DataNode := True;
  58. Result^.Data := AData;
  59. Result^.ChildCount := 0;
  60. end;
  61. function CreateNode(const AKey : TKeyType) : PTrieNode;
  62. begin
  63. New(Result);
  64. Result^.Key := AKey;
  65. Result^.DataNode := False;
  66. Result^.ChildCount := 0;
  67. end;
  68. procedure FreeNode(ANode : PTrieNode);
  69. var
  70. p : PTrieNode;
  71. i : Integer;
  72. begin
  73. if (ANode = nil) then
  74. exit;
  75. p := ANode;
  76. for i := 0 to p^.ChildCount - 1 do
  77. FreeNode(p^.Children[i]);
  78. Dispose(p);
  79. end;
  80. function InsertWord(
  81. const ARoot : PTrieNode;
  82. const AWord : TKeyType;
  83. const AValue : TDataType
  84. ) : Boolean;
  85. begin
  86. Result := InsertWord(ARoot,[AWord],AValue);
  87. end;
  88. function InsertWord(
  89. const ARoot : PTrieNode;
  90. const AWord : array of TKeyType;
  91. const AValue : TDataType
  92. ) : Boolean;
  93. var
  94. p : PTrieNode;
  95. i, k, c : Integer;
  96. searching : TKeyType;
  97. found : Boolean;
  98. begin
  99. Result := False;
  100. if (ARoot^.Key <> AWord[0]) then
  101. exit;
  102. p := ARoot;
  103. i := 1;
  104. c := Length(AWord);
  105. while (i < c) do begin
  106. searching := AWord[i];
  107. found := False;
  108. for k := 0 to p^.ChildCount - 1 do begin
  109. if (p^.Children[k]^.Key = searching) then begin
  110. p := p^.Children[k];
  111. found := True;
  112. Break;
  113. end;
  114. end;
  115. if not found then
  116. Break;
  117. Inc(i);
  118. end;
  119. if (i < c) then begin
  120. if (i = c) then
  121. i := i - 1;
  122. for i := i to c - 2 do begin
  123. k := p^.ChildCount;
  124. p^.Children[k] := CreateNode(AWord[i]);
  125. p^.ChildCount := k + 1;
  126. p := p^.Children[k];
  127. end;
  128. i := c - 1;
  129. k := p^.ChildCount;
  130. p^.Children[k] := CreateNode(AWord[i],AValue);
  131. p^.ChildCount := k + 1;
  132. Result := True;
  133. end;
  134. end;
  135. end.