Advertisement
Guest User

Untitled

a guest
Nov 20th, 2017
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.18 KB | None | 0 0
  1. #include "trie.hpp"
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>    
  5.  
  6. bool hasAnotherWord = false;
  7.  
  8. trie_node* find(const std::string &str,trie_node* root) {
  9.     trie_node* currentNode = root;
  10.     const char* sptr = str.c_str();
  11.     while (*sptr) {
  12.         if(currentNode->children[*sptr] == nullptr) {
  13.             throw 20;
  14.         }
  15.         currentNode = currentNode->children[*sptr];
  16.         sptr++;
  17.     }
  18.     return currentNode;
  19. }
  20.  
  21. trie_node* addChild(trie_node* node,char child,bool terminal,size_t &size) {
  22.     trie_node* newNode = new trie_node;
  23.     newNode->payload = child;
  24.     newNode->is_terminal = terminal;
  25.     newNode->parent = node;
  26.     if(terminal) {
  27.         size++;
  28.     }
  29.     node->children[child] = newNode;
  30.     hasAnotherWord = true;
  31.     return newNode;
  32. }
  33.  
  34. bool trie::contains(const std::string& str) const {
  35.     if(str.empty() && m_root->is_terminal == true) {
  36.         return true;
  37.     } else if(str.empty()) {
  38.         return false;
  39.     }
  40.     try {
  41.         trie_node* node = find(str,m_root);
  42.         if(node->is_terminal) {
  43.             return true;
  44.         } else {
  45.             return false;
  46.         }
  47.     }catch(int e) {
  48.         if(e ==20) {
  49.             return false;
  50.         }
  51.     }
  52.     return false;
  53. }
  54.  
  55.  
  56. bool trie::insert(const std::string& str) {
  57.     if(contains(str)) {
  58.         return false;
  59.     } else {
  60.         if(str.empty()) {
  61.             m_root->is_terminal = true;
  62.             m_size++;
  63.             return true;
  64.         }
  65.         trie_node* currentNode = m_root;
  66.         const char* sptr = str.c_str();
  67.         int length = 1;
  68.  
  69.         while (*sptr) {
  70.             if(currentNode->children[*sptr] == nullptr) {
  71.                 currentNode = addChild(currentNode,*sptr,length==str.length(),m_size);
  72.                 length++;
  73.             }else {
  74.                 currentNode = currentNode->children[*sptr];
  75.                 if(length == str.length()) {
  76.                     currentNode->is_terminal = true;
  77.                     m_size++;
  78.                 }
  79.                 length++;
  80.             }
  81.             sptr++;
  82.         }
  83.         return true;
  84.     }
  85. }
  86.  
  87. void deallocate_node(trie_node* node) {
  88.     for(int i = 0;i<128;i++) {
  89.         if(node->children[i] != nullptr) {
  90.             deallocate_node(node->children[i]);
  91.         }
  92.     }
  93.     delete node;
  94. }
  95.  
  96.  
  97.  
  98.  
  99. bool trie::erase(const std::string& str) {
  100.     try {
  101.         trie_node* nodeToErase = find(str,m_root);
  102.         if(nodeToErase->is_terminal == true) {
  103.             nodeToErase->is_terminal = false;
  104.             m_size--;
  105.         } else {
  106.             return false;
  107.         }
  108.     }catch(int e) {
  109.         if(e == 20)
  110.             return false;
  111.     }
  112.     return true;
  113. }
  114.  
  115. std::vector<std::string> trie::search_by_prefix(const std::string& prefix) const {
  116.     std::vector<std::string> foundWords;
  117.     trie_node* currentNode = find(prefix,m_root);
  118.     word_cursor* cursor = new word_cursor(currentNode);
  119.     if(!currentNode->is_terminal) {
  120.         cursor->move_to_next_word();
  121.     }
  122.     while(cursor->has_word()) {
  123.         foundWords.push_back(cursor->read_word());
  124.         cursor->move_to_next_word();
  125.     }
  126.     delete cursor;
  127.     return foundWords;
  128. }
  129. std::vector<std::string> trie::get_prefixes(const std::string& str) const {
  130.     std::vector<std::string> prefixes;
  131.     trie_node* currentNode;
  132.     std::string workingString = str;
  133.     getprefixes:
  134.     try {
  135.         currentNode = find(workingString,m_root);
  136.     } catch(int e) {
  137.         if(e ==20) {
  138.             workingString = workingString.substr(0,workingString.length()-2);
  139.             goto getprefixes;
  140.         }
  141.     }
  142.     int index = 0;
  143.     while(true) {
  144.         if(currentNode->is_terminal) {
  145.             prefixes.push_back(workingString.substr(0,workingString.length()-index));
  146.         }
  147.         currentNode = currentNode->parent;
  148.         if(currentNode == m_root) {
  149.             break;
  150.         }
  151.         index++;
  152.     }
  153.     return prefixes;
  154. }
  155.  
  156.  
  157. word_cursor trie::get_word_cursor() const {
  158.     word_cursor cursor = word_cursor(m_root);
  159.     if(!m_root->is_terminal) {
  160.         cursor.move_to_next_word();
  161.     }
  162.     return cursor;
  163. }
  164.  
  165.  
  166. size_t trie::size() const {
  167.     return m_size;
  168. }
  169.  
  170. bool trie::empty() const {
  171.     return m_size == 0;
  172. }
  173.  
  174. trie::trie(const std::vector<std::string>& strings) :
  175. m_root(new trie_node)
  176. {
  177.     for(size_t i= 0;i<strings.size();i++) {
  178.         insert(strings[i]);
  179.     }
  180. }
  181.  
  182.  
  183. trie::trie() :
  184. m_root(new trie_node) {
  185.  
  186. }
  187.  
  188.  
  189. trie::~trie() {
  190.     deallocate_node(m_root);
  191.     m_size = 0;
  192.  
  193. }
  194. word_cursor::word_cursor(const trie_node* word_ptr):
  195. m_ptr(word_ptr){
  196.  
  197.  
  198. }
  199. bool word_cursor::has_word() const {
  200.     return hasAnotherWord;
  201. }
  202. std::string word_cursor::read_word() const {
  203.     const trie_node* currentNode = m_ptr;
  204.     std::string word = "";
  205.     while(true) {
  206.         if(currentNode->payload ==  '\0') {
  207.             break;
  208.         }
  209.         word += currentNode->payload;
  210.         currentNode = currentNode->parent;
  211.  
  212.     }
  213.     std::reverse(word.begin(),word.end());  
  214.     return word;
  215. }
  216.  
  217. void word_cursor::move_to_next_word() {
  218.     nextword:
  219.     std::string word = read_word();
  220.  
  221.     for(int i = 0;i<128;i++) {
  222.         if(m_ptr->children[i] != nullptr) {
  223.             m_ptr = m_ptr->children[i];
  224.             if(!m_ptr->is_terminal) {
  225.                 goto nextword;
  226.                 return;
  227.             } else if(m_ptr->is_terminal){
  228.                 return;
  229.             }
  230.         }
  231.     }
  232.     int index = 1;  
  233.     while(m_ptr->payload != '\0') {
  234.         m_ptr = m_ptr->parent;
  235.         // m_ptr = return_to_root(m_ptr);
  236.         for(int i = 0;i<128;i++) {
  237.             if(m_ptr->children[i] != nullptr) {
  238.                 if(m_ptr->children[i]->payload <= word[word.length()-index]) {
  239.                     continue;
  240.                 } else if(!m_ptr->children[i]->is_terminal) {
  241.                     m_ptr = m_ptr->children[i];
  242.                     goto nextword;
  243.                 } else if(m_ptr->children[i]->is_terminal) {
  244.                     m_ptr = m_ptr->children[i];
  245.                     return;
  246.                 }
  247.             }
  248.         }
  249.         index++;
  250.     }
  251.     hasAnotherWord = false;
  252. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement