Advertisement
dmitry_borisenkov

Untitled

Nov 17th, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.10 KB | None | 0 0
  1. #include <algorithm>
  2. #include <vector>
  3. #include <string>
  4. #include <memory>
  5. #include <cassert>
  6. #include <iostream>
  7.  
  8. class PrefixNode {
  9.   // TODO: replace with more efficient data structure for lookup
  10.   using children_t = std::vector<std::unique_ptr<PrefixNode>>;
  11.   char Letter;
  12.   bool Terminator { false };
  13.   children_t Children;
  14. public:
  15.   PrefixNode(char letter);
  16.   // \brief add new children if \p letter doesn't exist.
  17.   // \return pointer to the node with \p letter.
  18.   PrefixNode *addChildren(char letter);
  19.   PrefixNode *hasChildren(char letter) const;
  20.   // \brief mark the Node as last character of a word
  21.   void endOfWord() { Terminator = true; }
  22.   bool isTerminator() const { return Terminator; }
  23. };
  24.  
  25. class Dictionary {
  26.   PrefixNode Root;
  27. public:
  28.   Dictionary() : Root{'\0'} {}
  29.   bool exist(const std::string& word) const ;
  30.   void add(const std::string& word);
  31. };
  32.  
  33. PrefixNode::PrefixNode(char letter) : Letter{ letter }, Children(26) {}
  34.  
  35. // We assume we have 26 preallocated default constructed children
  36. PrefixNode *PrefixNode::addChildren(char letter) {
  37.   assert(letter >= 'a' && letter <= 'z' && "Non letter character");
  38.   auto& letterNode = Children[letter - 'a'];
  39.   if (!letterNode)
  40.     letterNode.reset(new PrefixNode(letter));
  41.   return letterNode.get();
  42. }
  43.  
  44. PrefixNode *PrefixNode::hasChildren(char letter) const {
  45.   assert(letter >= 'a' && letter <= 'z' && "Non letter character");
  46.   return Children[letter - 'a'].get();
  47. }
  48.  
  49. void Dictionary::add(const std::string& word) {
  50.   PrefixNode *currentNode { &Root };
  51.   for (auto letter : word) {
  52.     currentNode = currentNode->addChildren(letter);
  53.   }
  54.   currentNode->endOfWord();
  55. }
  56.  
  57. bool Dictionary::exist(const std::string& word) const {
  58.   const PrefixNode *currentNode { &Root };
  59.   for (auto letter : word) {
  60.     currentNode = currentNode->hasChildren(letter);
  61.     if (!currentNode)
  62.       return false;
  63.   }
  64.   return currentNode->isTerminator();
  65. }
  66.  
  67. void readWordsFromStdin(Dictionary& dictionary) {
  68.   std::string word;
  69.   while (std::cin >> word) {
  70.     if (word.empty())
  71.       break;
  72.     dictionary.add(word);
  73.   }
  74. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement