1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
#include <iostream>
#include <string>
#include <memory>
#include <cctype>
struct WordSearch {
void insert( const std::string& word ) {
node* curr = root.get() ;
for( char c : word ) {
c = std::tolower(c) ;
if( curr->letter == 0 ) curr->letter = c ; // null character, use this node
node* n = curr->find(c) ;
if( n == nullptr ) n = curr->append(c) ; // not found, append it
// if subtrie is empty, add a sentinel node (makes the code easier)
if( n->sub == nullptr ) n->sub = std::make_unique<node>(0) ;
curr = n->sub.get() ; // go down to the next level
}
curr->end_of_word = true ;
}
bool search( const std::string& word ) const {
const node* curr = root.get() ;
for( char c : word ) {
c = std::tolower(c) ;
const node* n = curr ? curr->find(c) : nullptr ;
if( n == nullptr ) return false ;
else curr = n->sub.get() ;
}
return curr && curr->end_of_word ;
}
private:
struct node {
using pointer = std::unique_ptr<node> ;
char letter ; // letters
bool end_of_word = false ; // end
pointer next ; // main
pointer sub ; // subs
explicit node( char c ) : letter(c) {}
node* find( char c ) { // locate node with letter == c in this list
if( c == letter ) return this ;
for( node* p = next.get() ; p != nullptr ; p = p->next.get() )
if( p->letter == c ) return p ;
return nullptr ; // not found
}
const node* find( char c ) const {
return const_cast<node*>(this)->find(c) ;
}
node* append( char c ) { // append node with letter == c to this list
node* p = this ;
// bump p to get to the last node in the list
while( p->next != nullptr ) p = p->next.get() ;
p->next = std::make_unique<node>(c) ; // append a new node as the next of p
return p->next.get() ;
}
};
// note: a null char character is used for the sentinel leaf node
node::pointer root = std::make_unique<node>(0) ;
};
int main()
{
WordSearch ws ;
std::cout << "insert:\n " ;
for( std::string word : { "change", "any", "and", "an", "all", "pointers", "to", "unique", "pointers" } ) {
std::cout << word << ' ' ;
ws.insert(word) ;
}
std::cout << "\n\n" ;
for( std::string word : { "change", "many", "Any", "allot", "all", "an", "AND", "pointers", "point" } )
std::cout << word << " : " << ( ws.search(word) ? "found\n" : "not found\n" ) ;
}
|