00001 #ifndef TrieBase_HPP
00002 #define TrieBase_HPP
00003
00004 #include "common.hpp"
00005 #include <stack>
00006
00012 template <class EDGELIST, typename DATA = counter_t >
00013 class TrieBase
00014 {
00015 protected:
00016 DATA data;
00017 EDGELIST edgelist;
00018
00019 public:
00020 class iterator
00021 {
00022 private:
00023 typedef std::pair< typename EDGELIST::iterator,
00024 TrieBase<EDGELIST, DATA>* > itpair_t;
00025 std::stack<itpair_t> node_stack;
00026 std::vector<item_t> itemset;
00027 public:
00028 iterator(){}
00029 iterator(typename EDGELIST::iterator it, TrieBase* trie)
00030 {
00031 node_stack.push(itpair_t(it, trie));
00032 }
00033
00034
00035 void operator++()
00036 {
00037 while( (node_stack.top().first == node_stack.top().
00038 second->edgelist.end()) )
00039 {
00040 node_stack.pop();
00041 itemset.pop_back();
00042 if(!node_stack.empty())
00043 ++node_stack.top().first;
00044 else
00045 break;
00046 }
00047 if(!node_stack.empty())
00048 {
00049 itemset.push_back( (*node_stack.top().first).first );
00050 node_stack.push(
00051 itpair_t( static_cast<TrieBase<EDGELIST, DATA>*>
00052 ((*node_stack.top().first).second)->edgelist.begin(),
00053 static_cast<TrieBase<EDGELIST, DATA>*>
00054 ((*node_stack.top().first).second) ));
00055 }
00056
00057 }
00058
00059
00060
00061
00062
00063
00064
00065 std::pair<std::vector<item_t>, DATA> operator*() const
00066 {
00067 return std::pair<std::vector<item_t>, DATA>(
00068 itemset, node_stack.top().second->data );
00069 }
00070
00071 iterator& operator=(const iterator& an_it)
00072 {
00073 if( this != &an_it )
00074 {
00075 node_stack = an_it.node_stack;
00076 itemset = an_it.itemset;
00077 }
00078 return *this;
00079 }
00080 bool operator==(const iterator& an_it) const
00081 {
00082 return node_stack == an_it.node_stack;
00083 }
00084
00085 bool operator!=(const iterator& an_it) const
00086 {
00087 return node_stack != an_it.node_stack;
00088 }
00089 };
00090 static DATA def_data;
00091 TrieBase(){data = def_data;}
00092 TrieBase(DATA data) : data(data){}
00093 iterator begin(){return iterator(edgelist.begin(), this);}
00094 iterator end(){return iterator();}
00095
00096 void setData(DATA data)
00097 {this->data = data;}
00098
00099 DATA& getData()
00100 {return data;}
00101
00102
00104 void addLeaf( const item_t label)
00105 {
00106 edgelist.addEdge(label, new TrieBase(def_data));
00107 }
00108
00109
00110 bool isLeaf() const
00111 {
00112 return !edgelist.empty();
00113 }
00117 template <class CONT> bool isIncluded(
00118 const CONT& itemset,
00119 typename CONT::const_iterator it ) const;
00120
00121 template <class CONT> TrieBase& addItemset(
00122 const CONT& itemset,
00123 typename CONT::const_iterator it);
00124 };
00125
00134 template <class EDGELIST, typename DATA> template <class CONT> inline
00135 bool TrieBase<EDGELIST, DATA>::
00136 isIncluded( const CONT& itemset, typename CONT::const_iterator it ) const
00137 {
00138 if( it == itemset.end() ) return true;
00139 else
00140 {
00141 TrieBase* subtrie;
00142 edgelist.lookupNocheck(*it, subtrie);
00143 if(subtrie)
00144 return static_cast<TrieBase*>(static_cast<TrieBase*>(subtrie))->
00145 isIncluded<CONT>( itemset, ++it );
00146 else
00147 return false;
00148 }
00149 }
00150
00151 template <class EDGELIST, typename DATA> template <class CONT> inline
00152 TrieBase<EDGELIST, DATA>& TrieBase<EDGELIST, DATA>::addItemset(
00153 const CONT& itemset, typename CONT::const_iterator it)
00154 {
00155 if( it == itemset.end() )
00156 return *this;
00157 else
00158 {
00159 TrieBase** subtrie = reinterpret_cast<TrieBase**>(&edgelist.findOrCreate(*it));
00160 if(*subtrie == NULL)
00161 *subtrie = new TrieBase();
00162 return (*subtrie)->addItemset( itemset, ++it );
00163 }
00164
00165 }
00166
00167 #endif