Guest User

Untitled

a guest
Jul 19th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.23 KB | None | 0 0
  1. #include <iostream>
  2. #include <climits>
  3.  
  4. // Implmentation of trie structure for checking membership of large set of strings
  5.  
  6. #define TRIE_SIZE SCHAR_MAX + 1
  7.  
  8. struct TrieState
  9. {
  10. enum Kind
  11. {
  12. Empty,
  13. Part,
  14. End
  15. };
  16. };
  17.  
  18. class TrieNode
  19. {
  20. public:
  21. static void cleanChildren(TrieNode** child)
  22. {
  23. for(size_t i = 0; i < TRIE_SIZE ; i++)
  24. child[i] = nullptr;
  25. }
  26. TrieNode()
  27. {
  28. TrieNode::cleanChildren(_children);
  29. }
  30. ~TrieNode()
  31. {
  32. for(size_t i = 0; i < TRIE_SIZE ; i++)
  33. delete _children[i];
  34. }
  35. // Trie is indexed with char type
  36. TrieState::Kind& stateAt(char index)
  37. {
  38. return _states[index % TRIE_SIZE];
  39. }
  40.  
  41. // Trie is indexed with char type.
  42. TrieNode* childAt(char index) const
  43. {
  44. return _children[index % TRIE_SIZE];
  45. }
  46.  
  47. void setChildAt(TrieNode* child, char index)
  48. {
  49. _children[index % TRIE_SIZE] = child;
  50. }
  51.  
  52. bool isEmptyAt(char index) const
  53. {
  54. return _children[index % TRIE_SIZE] == nullptr;
  55. }
  56. private:
  57. TrieNode* _children[TRIE_SIZE];
  58. TrieState::Kind _states[TRIE_SIZE];
  59. };
  60.  
  61. // Used for manufacturing instances of tries, and inserting strings.
  62. class TrieManager
  63. {
  64. public:
  65. static void insert(TrieNode* trie, const char* string)
  66. {
  67. TrieNode* traverse = trie;
  68. char indexKey;
  69. // Does not insert anything if string is empty
  70. while(*(string + 1))
  71. {
  72. indexKey = *string++;
  73. switch(traverse->stateAt(indexKey))
  74. {
  75. case TrieState::Empty:
  76. traverse->setChildAt(new TrieNode(), indexKey);
  77. traverse->stateAt(indexKey) = TrieState::Part;
  78. traverse = traverse->childAt(indexKey);
  79. break;
  80. case TrieState::Part:
  81. traverse = traverse->childAt(indexKey);
  82. break;
  83. case TrieState::End:
  84. traverse->stateAt(indexKey) = TrieState::Part;
  85. traverse = traverse->childAt(indexKey);
  86. break;
  87. }
  88. }
  89. // handles last character in string.
  90. indexKey = *string;
  91. switch(traverse->stateAt(indexKey))
  92. {
  93. case TrieState::Empty:
  94. traverse->stateAt(indexKey) = TrieState::End;
  95. break;
  96. case TrieState::Part:
  97. case TrieState::End:
  98. return;
  99. }
  100. }
  101.  
  102. static bool contains(TrieNode* trie, const char* string)
  103. {
  104. TrieNode* traverse = trie;
  105. while(*string)
  106. {
  107. switch(traverse->stateAt(*string))
  108. {
  109. case TrieState::Empty:
  110. return false;
  111. case TrieState::Part:
  112. traverse = traverse->childAt(*string);
  113. string++;
  114. break;
  115. case TrieState::End:
  116. return true;
  117.  
  118. }
  119. }
  120. return false;
  121. }
  122.  
  123. static void printFirst(TrieNode* trie)
  124. {
  125. for(char i = 0; i < SCHAR_MAX; i++)
  126. {
  127. switch(trie->stateAt(i))
  128. {
  129. case TrieState::Part:
  130. std::cout << i;
  131. TrieManager::printFirst(trie->childAt(i));
  132. return;
  133. case TrieState::End:
  134. std::cout << i << '\n';
  135. return;
  136. case TrieState::Empty:
  137. break;
  138. }
  139. }
  140. }
  141. };
  142.  
  143.  
  144.  
  145.  
  146. int main(int argc, char const *argv[])
  147. {
  148. TrieNode* trie = new TrieNode();
  149. TrieManager::insert(trie, "Foo!");
  150. TrieManager::insert(trie, "Doo!");
  151. TrieManager::insert(trie, "Food!");
  152. TrieManager::insert(trie, "Aaaaaaa");
  153. std::cout << "Contains Doo! " << TrieManager::contains(trie, "Doo!") << "\n";
  154. TrieManager::printFirst(trie);
  155. delete trie;
  156. return 0;
  157. }
Add Comment
Please, Sign In to add comment