dictionnary.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /**
  2. * This file is part of Gomu.
  3. *
  4. * Copyright 2016 by Jean Fromentin <jean.fromentin@math.cnrs.fr>
  5. *
  6. * Gomu is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Gomu is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Gomu. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef DICTIONNARY_HPP
  20. #define DICTIONNARY_HPP
  21. #include <iostream>
  22. #include <string>
  23. #include <deque>
  24. using namespace std;
  25. //**********************
  26. //* Class declarations *
  27. //**********************
  28. //! Class representing a dictionnary node
  29. template<class T> class DictionnaryNode{
  30. public:
  31. //!Info attached to a DictionnaryNode
  32. T* info;
  33. //!Sons of the dictionnary node
  34. deque<DictionnaryNode<T>*> sons;
  35. //! Letter of the node
  36. char letter;
  37. //! The empty constructor
  38. DictionnaryNode();
  39. //! Destructor
  40. ~DictionnaryNode();
  41. //! Add a word to the dictionnary at this node
  42. //! \param op the word to addd
  43. //! \param info information attached to the word
  44. void add(string op,T* info);
  45. //! Display word obatained from this node preceded by a prefix
  46. //! \param preffix the preffix of the node (ie the path from the root to the current node)
  47. void disp(const string& preffix) const;
  48. };
  49. //! A class representing a dictionnary
  50. template<class T> class Dictionnary{
  51. private:
  52. //! Root node
  53. DictionnaryNode<T>* root;
  54. public:
  55. //! Empty constructor
  56. Dictionnary();
  57. //! Destructor
  58. ~Dictionnary();
  59. //! Add a word to the distionnary
  60. //! \param op the word to add
  61. //! \param indo information attached to the word
  62. //! \retrun Return true if the word has bee added, false otherwise
  63. bool add(string op,T* info);
  64. //! Display the dictionnary
  65. void disp() const;
  66. //! Find a maximal preffix of a suffix of a word in the dictionnary
  67. //! \param pos position of the first letter of the suffix
  68. //! \param str the full word
  69. //! \return Information attached to a maximal preffix or nullptr otherwise
  70. T* find_at(size_t& pos,const string& str);
  71. };
  72. //*************************
  73. //* Function declarations *
  74. //*************************
  75. //------------------------------------
  76. // DictionnaryNode::DictionnaryNode()
  77. //------------------------------------
  78. template<class T> inline
  79. DictionnaryNode<T>::DictionnaryNode(){
  80. info=nullptr;
  81. }
  82. //------------------------------------
  83. // DictionnaryNode::~DictionnaryNode()
  84. //------------------------------------
  85. template<class T>
  86. DictionnaryNode<T>::~DictionnaryNode(){
  87. if(info!=nullptr) delete info;
  88. for(auto it=sons.begin();it!=sons.end();++it) delete *it;
  89. }
  90. //--------------------------------------
  91. // DictionnaryNode::disp(const string&)
  92. //--------------------------------------
  93. template<class T> void
  94. DictionnaryNode<T>::disp(const string& preffix) const{
  95. string npreffix=preffix+letter;
  96. if(info!=nullptr) cout<<npreffix<<" : "<<info->func<<endl;
  97. for(auto it=sons.begin();it!=sons.end();++it) (*it)->disp(npreffix);
  98. }
  99. //----------------------------
  100. // Dictionnary::Dictionnary()
  101. //----------------------------
  102. template<class T> inline
  103. Dictionnary<T>::Dictionnary(){
  104. root=new DictionnaryNode<T>();
  105. }
  106. //----------------------------
  107. // Dictionnary::~Dictionnary()
  108. //----------------------------
  109. template<class T> inline
  110. Dictionnary<T>::~Dictionnary(){
  111. if(root!=nullptr) delete root;
  112. }
  113. //---------------------
  114. // Dictionnary::disp()
  115. //---------------------
  116. template<class T> inline void
  117. Dictionnary<T>::disp() const{
  118. for(auto it=root->sons.begin();it!=root->sons.end();++it) (*it)->disp("");
  119. }
  120. //-----------------------------
  121. // Dictionnary::add(string,T*)
  122. //-----------------------------
  123. template<class T> bool
  124. Dictionnary<T>::add(string op,T* info){
  125. DictionnaryNode<T>* cur=root;
  126. size_t pos=0;
  127. size_t end=op.length();
  128. //Search maximal prefix
  129. while(pos<end){
  130. char l=op[pos];
  131. auto it=cur->sons.begin();
  132. for(;it!=cur->sons.end();++it){
  133. if((*it)->letter==l) break;
  134. }
  135. if(it==cur->sons.end()) break;//the letter not occur
  136. cur=*it;
  137. ++pos;
  138. }
  139. //If the prefix is the whole word
  140. if(pos==end){
  141. if(cur->info!=nullptr){
  142. cout<<"Warning : entry "<<op<<" already exists"<<endl;
  143. return false;
  144. }
  145. else{
  146. cur->info=info;
  147. }
  148. }
  149. //Adding suffix to dictionnary
  150. while(pos<end){
  151. DictionnaryNode<T>* ncur=new DictionnaryNode<T>();
  152. ncur->letter=op[pos];
  153. cur->sons.push_back(ncur);
  154. cur=ncur;
  155. ++pos;
  156. }
  157. cur->info=info;
  158. return true;
  159. }
  160. //---------------------------------------------
  161. // Dictionnary::find_at(size_t&,const string&)
  162. //---------------------------------------------
  163. template<class T> T*
  164. Dictionnary<T>::find_at(size_t& pos,const string& str){
  165. size_t end=str.length();
  166. size_t npos=pos;
  167. string path="";
  168. T* res=nullptr;
  169. DictionnaryNode<T>* cur=root;
  170. while(pos<end){
  171. char l=str[npos];
  172. auto it=cur->sons.begin();
  173. for(;it!=cur->sons.end();++it){
  174. if((*it)->letter==l) break;
  175. }
  176. if(it==cur->sons.end()) break;//the letter not occur
  177. cur=*it;
  178. path+=l;
  179. if(cur->info!=nullptr){
  180. res=cur->info;
  181. pos=npos+1;
  182. }
  183. ++npos;
  184. }
  185. return res;
  186. }
  187. #endif