#ifndef TRIE_HPP #define TRIE_HPP #include #include #include #include "../Relationship/Relationship.hpp" #define TrieRelationship map #define TrieKids map #define RelatedTries multimap using namespace std; class Trie { public: Trie () : fullword(false), letter('\0'), parent(NULL) {}; Trie (Trie * newparent, char newletter) : fullword(false), letter(newletter), parent(newparent) {}; void AddWord(const string newword); Trie * FindWord(string newword); string GetName(); void Relate(Trie * sibling, const int score); void Repr(string leader); private: bool fullword; char letter; Trie *parent; TrieRelationship related; TrieKids children; Trie * CreateChild(const char letter); void GiveRelate(RelatedTries & list); void SetFinal() { fullword = true; }; }; #endif #include "Trie.hpp" void Trie::GiveRelate(RelatedTries & list) { if ( ! fullword) throw "Trie:Giverelate needs a full word to relate"; TrieRelationship::iterator it; for (it = related.begin(); it != related.end(); ++it) { string name = it->first->GetName(); int score = it->second->GetScore(); list.insert(make_pair(score,name)); } } void Trie::Relate(Trie * Sibling, const int score) { if (! Sibling) throw "Sibling is null pointer"; Relationship * relate; TrieRelationship::iterator it; it = related.find(Sibling); if (it != related.end()) relate = it->second; else { relate = new Relationship(); related[Sibling] = relate; } relate->Bump(score); } void Trie::AddWord(const string newword) { Trie * child; TrieKids::iterator childit; char firstletter; if (newword.size() < 1) throw "Trie::Addword can not add zero length strings"; firstletter = newword[0]; childit = children.find(firstletter); if (childit != children.end()) child = childit->second; else { child = new Trie(this, firstletter); children[firstletter] = child; } if (newword.size() == 1) child->SetFinal(); else { string rest = newword.substr(1); child -> AddWord(rest); } } Trie * Trie::FindWord(const string newword) { TrieKids::iterator childit; if (newword.size() == 0) if (fullword) return this; else return NULL; char first = newword.substr(0,1).c_str()[0]; childit = children.find(first); if (childit == children.end()) return NULL; return childit->second->FindWord(newword.substr(1)); } string Trie::GetName() { if (parent) return parent->GetName() + letter; else return string(); } void Trie::Repr(string leader) { if (fullword) { cout << leader << letter << endl; TrieRelationship::iterator relit; for (relit = related.begin(); relit != related.end(); ++relit) { string name = relit->first->GetName(); int score = relit->second->GetScore(); cout << " " << name << "(" << score << ")" << endl; } } TrieKids::iterator it; for (it = children.begin(); it != children.end(); ++it) if (parent) it->second->Repr(leader + letter); else it->second->Repr(leader); }