Guest User

Untitled

a guest
Jan 19th, 2019
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.53 KB | None | 0 0
  1. /*************************************************************************
  2.                            intl_finder  -  description
  3.                              -------------------
  4.     début                : 5 oct. 2012
  5.     copyright            : (C) 2012 par tcantenot
  6. *************************************************************************/
  7.  
  8. //---------- Interface de la classe <intl_finder> (fichier intl_finder.h) ------
  9. #ifndef __INTL_FINDER_H__
  10. #define __INTL_FINDER_H__
  11.  
  12. //--------------------------------------------------- Interfaces utilisées
  13.  
  14. #include <iostream>
  15.  
  16. #include "rb_tree.h"
  17. #include "list.h"
  18.  
  19. namespace tp_cpp_1 {
  20.     //------------------------------------------------------------------ Types
  21.    
  22.     typedef unsigned long long int size_t;
  23.  
  24.     template<class T>
  25.     struct free {
  26.         void operator()(T * & __e) {
  27.             delete __e;
  28.         }
  29.     };
  30.    
  31.     template<class T>
  32.     struct show {
  33.         void operator()(T const & __e) const {
  34.             std::cout << __e;
  35.         }
  36.     };
  37.    
  38.     struct hash_char {
  39.         size_t operator()(char __c) const {
  40.             return static_cast<size_t>(__c + 128);
  41.         }
  42.     };
  43.    
  44.     struct inv_hash_char {
  45.         char operator()(size_t __s) {
  46.             return static_cast<char>(__s - 128);
  47.         }
  48.     };
  49.  
  50.     //------------------------------------------------------------------------
  51.     // Rôle de la classe <intl_finder>
  52.     //
  53.     //
  54.     //------------------------------------------------------------------------
  55.     template<class T, class Hash, class InvHash, const size_t MAX_SOURCE, const size_t MAX_DATA, const T End = T(0)>
  56.     class intl_finder {
  57.     //----------------------------------------------------------------- PUBLIC
  58.  
  59.     public:
  60.     //----------------------------------------------------- Méthodes publiques
  61.         void Display(size_t __source) const;
  62.         // Mode d'emploi :
  63.         //
  64.         // Contrat :
  65.         //
  66.  
  67.         bool Add(T const & __data, size_t __source);
  68.         // Mode d'emploi :
  69.         //      Ajoute un élément de communication (__data) pour une planète source (__source)
  70.         //      Renvoie true si l'ajout a réussi, false sinon.
  71.         //
  72.         // Contrat :
  73.         //      L'indice __source d'une planète est compris entre 1 et 128 (inclus).
  74.         //
  75.  
  76.         bool Add(T const * __data, size_t __source);
  77.         // Mode d'emploi :
  78.         //      Ajoute un ensemble d'éléments de communication sous forme d'un tableau de caractères
  79.         //      (__data) pour une planète source (__source)
  80.         //      Renvoie true si l'ajout a réussi, false sinon.
  81.         //
  82.         // Contrat :
  83.         //      L'indice __source d'une planète est compris entre 1 et 128 (inclus).
  84.         //
  85.  
  86.         size_t Count(size_t __source) const;
  87.         // Mode d'emploi :
  88.         //      Renvoie le nombre d'éléments de communication de la planète d'indice __source
  89.         //
  90.         // Contrat :
  91.         //      L'indice __source d'une planète est compris entre 1 et 128 (inclus).
  92.         //
  93.  
  94.         size_t FindIntl(T const * __pattern, size_t __from_pos, size_t & __source) const;
  95.         // Mode d'emploi :
  96.         //      Retourne la première occurence du mot clé __pattern trouvée dans les données
  97.         //      à partir de l'indice __from_pos
  98.         //      Récupération de l'indice de la planète dont les données contiennent la première
  99.         //      occurence via (la référence) __source.
  100.         //
  101.         // Contrat :
  102.         //      __from_pos doit être compris entre 0 et (10 000 000 - longueur(__pattern)).
  103.  
  104.  
  105.         T const & GetData(size_t __pos, int * __error = nullptr) const;
  106.         T & GetData(size_t __pos, int * __error = nullptr);
  107.         // Mode d'emploi :
  108.         //      Retourne l'élément de communication à la position "__pos"
  109.         //      __error vaut 0 si la chaine est trouvée, -1 sinon
  110.         // Contrat :
  111.         //
  112.  
  113.  
  114.     //-------------------------------------------- Constructeurs - destructeur
  115.  
  116.         intl_finder(Hash __hash = Hash(), InvHash __inv_hash = InvHash());
  117.         // Mode d'emploi (constructeur par défault): trivial
  118.         //
  119.         // Contrat : aucun
  120.         //
  121.  
  122.         virtual ~intl_finder();
  123.         // Mode d'emploi (destructeur) : trivial
  124.         //
  125.         // Contrat : aucun
  126.         //
  127.  
  128.  
  129.     //------------------------------------------------------------------ PRIVE
  130.  
  131.     private:
  132.         struct source {
  133.             source() : count(0), ls() {
  134.                 for(size_t i = 0 ; i < MAX_DATA ; ++i)
  135.                     tree[i] = nullptr;
  136.             }
  137.            
  138.             ~source() {
  139.                 for(size_t i = 0 ; i < MAX_DATA ; ++i) {
  140.                     if(tree[i] != nullptr)
  141.                         tree[i]->preorder_map(free<size_t>());
  142.                    
  143.                     delete tree[i];
  144.                 }
  145.             }
  146.            
  147.             size_t count;
  148.             rb_tree<size_t> * tree[MAX_DATA];
  149.             list<T> ls;
  150.            
  151.             private:
  152.                 source(source const & __other) = delete;
  153.                 source const & operator=(source const & __other) = delete;
  154.         };
  155.        
  156.     //----------------------------------------------------- Méthodes protégées
  157.        
  158.         intl_finder(intl_finder const & __other) = delete; 
  159.         // Mode d'emploi (constructeur de copie) : trivial
  160.         // Mis dans la partie private afin que l'on ne puisse pas l'utiliser.
  161.         // Contrat : aucun
  162.         //
  163.        
  164.         intl_finder const & operator=(intl_finder const & __other) = delete;
  165.         // Mode d'emploi :
  166.         // Surcharge l'opérateur d'affectation
  167.         //
  168.         // Contrat : aucun
  169.         //
  170.                
  171.         bool contains(T const * __pattern, size_t & ___from_pos, size_t __pos, size_t __source) const;
  172.         // Mode d'emploi :
  173.         // Indique si la suite de caractères existe à partir de la position donnée
  174.         // parmi les éléments de communication de l'ensemble des planètes
  175.         //
  176.         // Contrat :
  177.         // Le numéro de la source doit être entre 1 et 128
  178.         //
  179.        
  180.     //----------------------------------------------------- Attributs protégés
  181.  
  182.         size_t _pos;
  183.         source * _sources[MAX_SOURCE];
  184.         Hash const & _hash;
  185.         InvHash const & _inv_hash;
  186.     };
  187.    
  188.     template<class T, class Hash, class InvHash, const size_t MAX_SOURCE, const size_t MAX_DATA, const T End>
  189.     intl_finder<T, Hash, InvHash, MAX_SOURCE, MAX_DATA, End>::intl_finder(Hash __hash, InvHash __inv_hash) : _pos(0), _hash(__hash), _inv_hash(__inv_hash) {
  190.         for(unsigned int i = 0 ; i < MAX_SOURCE ; ++i) {
  191.             _sources[i] = nullptr;
  192.         }
  193.     }
  194.    
  195.     template<class T, class Hash, class InvHash, const size_t MAX_SOURCE, const size_t MAX_DATA, const T End>
  196.     intl_finder<T, Hash, InvHash, MAX_SOURCE, MAX_DATA, End>::~intl_finder() {
  197.         for(unsigned int i = 0 ; i < MAX_SOURCE ; ++i)
  198.             delete _sources[i];
  199.     }
  200.    
  201.     template<class T, class Hash, class InvHash, const size_t MAX_SOURCE, const size_t MAX_DATA, const T End>
  202.     void intl_finder<T, Hash, InvHash, MAX_SOURCE, MAX_DATA, End>::Display(size_t __source) const {
  203.         if(__source == 0) {
  204.             for(size_t i = 1 ; i < MAX_SOURCE ; i++) {
  205.                 if(_sources[i] != nullptr) {
  206.                     std::cout << "Planete " << i << " : ";
  207.                     Display(i);
  208.                     std::cout << std::endl;
  209.                 }
  210.             }
  211.             return;
  212.         }
  213.        
  214.         if(__source > MAX_SOURCE)
  215.             return;
  216.         if(_sources[__source] == nullptr)
  217.             return;
  218.        
  219.         _sources[__source]->ls.map(show<T>());
  220.     }
  221.    
  222.     template<class T, class Hash, class InvHash, const size_t MAX_SOURCE, const size_t MAX_DATA, const T End>
  223.     bool intl_finder<T, Hash, InvHash, MAX_SOURCE, MAX_DATA, End>::Add(T const & __data, size_t __source) {
  224.         size_t c = _hash(__data);
  225.        
  226.         if(_sources[__source - 1] == nullptr)
  227.             _sources[__source - 1] = new source();
  228.        
  229.         if(_sources[__source - 1]->tree[c] == nullptr)
  230.             _sources[__source - 1]->tree[c] = new rb_tree<size_t>();
  231.        
  232.         _sources[__source - 1]->ls.push_back(__data);
  233.         _sources[__source - 1]->tree[c]->insert(new size_t(_pos));
  234.         _sources[__source - 1]->count++;
  235.         _pos++;
  236.        
  237.         return true;
  238.     }
  239.    
  240.     template<class T, class Hash, class InvHash, const size_t MAX_SOURCE, const size_t MAX_DATA, const T End>
  241.     bool intl_finder<T, Hash, InvHash, MAX_SOURCE, MAX_DATA, End>::Add(T const * __data, size_t __source) {
  242.         for(size_t i = 0 ; __data[i] != End && Add(__data[i], __source) ; ++i);
  243.         return true;
  244.     }
  245.    
  246.     template<class T, class Hash, class InvHash, const size_t MAX_SOURCE, const size_t MAX_DATA, const T End>
  247.     size_t intl_finder<T, Hash, InvHash, MAX_SOURCE, MAX_DATA, End>::Count(size_t __source) const {
  248.         if(__source > MAX_SOURCE)
  249.             return 0;
  250.        
  251.         if(__source == 0)
  252.             return _pos;
  253.        
  254.         if(_sources[__source - 1] == nullptr)
  255.             return 0;
  256.        
  257.         return _sources[__source - 1]->count;
  258.     }
  259.    
  260.     template<class T, class Hash, class InvHash, const size_t MAX_SOURCE, const size_t MAX_DATA, const T End>
  261.     T & intl_finder<T, Hash, InvHash, MAX_SOURCE, MAX_DATA, End>::GetData(size_t __pos, int * __error) {
  262.         if(__error != nullptr)
  263.             *__error = 0;
  264.        
  265.         for(size_t i = 0; i < MAX_SOURCE ; ++i)
  266.             for(size_t j = 0; j < MAX_DATA; ++j)
  267.                 if(_sources[i] != nullptr && _sources[i]->tree[j] != nullptr && _sources[i]->tree[j]->search(__pos) != nullptr)
  268.                     return _inv_hash(j);
  269.        
  270.         if(__error != nullptr)
  271.             *__error = -1;
  272.        
  273.         return 0;    
  274.     }
  275.    
  276.     template<class T, class Hash, class InvHash, const size_t MAX_SOURCE, const size_t MAX_DATA, const T End>
  277.     T const & intl_finder<T, Hash, InvHash, MAX_SOURCE, MAX_DATA, End>::GetData(size_t __pos, int * __error) const {
  278.         if(__error != nullptr)
  279.             *__error = 0;
  280.        
  281.         for(size_t i = 0; i < MAX_SOURCE ; ++i)
  282.             for(size_t j = 0; j < MAX_DATA; ++j)
  283.                 if(_sources[i] != nullptr && _sources[i]->tree[j] != nullptr && _sources[i]->tree[j]->search(__pos) != nullptr)
  284.                     return _inv_hash(j);
  285.        
  286.         if(__error != nullptr)
  287.             *__error = -1;
  288.        
  289.         return 0;    
  290.     }
  291.    
  292.     template<class T, class Hash, class InvHash, const size_t MAX_SOURCE, const size_t MAX_DATA, const T End>
  293.     size_t intl_finder<T, Hash, InvHash, MAX_SOURCE, MAX_DATA, End>::FindIntl(T const * __pattern, size_t __from_pos, size_t & __source) const {
  294.         size_t min_end = 0;
  295.         size_t min_source = 0;
  296.        
  297.         for(size_t i = 0 ; i < MAX_SOURCE ; ++i) {
  298.             size_t from = __from_pos;
  299.             if(contains(__pattern, from, 0, i + 1)) {
  300.                 if(min_end == 0 || from <= min_end) {
  301.                     min_end = from;
  302.                     min_source = i + 1;
  303.                 }
  304.             }
  305.         }
  306.        
  307.         if(min_source != 0) {
  308.             __source = min_source;
  309.             return *_sources[min_source - 1]->tree[_hash(__pattern[0])]->search_min_ranged(__from_pos);
  310.         }
  311.        
  312.         __source = 0;
  313.         return 0;
  314.     }
  315.    
  316.     template<class T, class Hash, class InvHash, const size_t MAX_SOURCE, const size_t MAX_DATA, const T End>
  317.     bool intl_finder<T, Hash, InvHash, MAX_SOURCE, MAX_DATA, End>::contains(T const * __pattern, size_t & __from_pos, size_t __pos, size_t __source) const {
  318.         if(_sources[__source - 1] == nullptr)   return false;
  319.         if(__pattern[__pos] == End) return true;
  320.        
  321.         size_t c = _hash(__pattern[__pos]);
  322.         if(_sources[__source - 1]->tree[c] == nullptr)  return false;
  323.        
  324.         size_t * new_from = _sources[__source - 1]->tree[c]->search_min_ranged(__from_pos);
  325.         if(new_from == nullptr) return false;
  326.        
  327.         __from_pos = *new_from + 1;
  328.         return contains(__pattern, __from_pos, __pos + 1, __source);
  329.     }
  330. }
  331.  
  332. //--------------------------- Autres définitions dépendantes de <intl_finder>
  333.  
  334. #endif // INTLFINDER_H_
Add Comment
Please, Sign In to add comment