Advertisement
a53

Numar_subsiruri_cu_arbori_de_sufixe

a53
Jan 1st, 2017
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.92 KB | None | 0 0
  1. /// Un program C++ pentru a gasi numarul de subsiruri distincte
  2. /// dintr-un sir folosind structuri de date de tip arbore
  3. #include <bits/stdc++.h>
  4. #define MAX_CHAR 26
  5. using namespace std;
  6.  
  7. /// Nodul arborelui de sufixe (arbore cu toate sufixele)
  8. class SuffixTrieNode
  9. {
  10. public:
  11. SuffixTrieNode *children[MAX_CHAR];
  12. SuffixTrieNode() /// Constructor
  13. {
  14. /// Initializarea tuturor pointerilor fii ca NULL
  15. for (int i = 0; i < MAX_CHAR; i++)
  16. children[i] = NULL;
  17. }
  18. /// O functie recursiva pentru a insera un sufix al lui s
  19. /// in subarborele cu radacina in acest nod
  20. void insertSuffix(string suffix);
  21. };
  22.  
  23. /// Arborele tuturor sufixelor
  24. class SuffixTrie
  25. {
  26. SuffixTrieNode *root;
  27. int _countNodesInTrie(SuffixTrieNode *);
  28. public:
  29. /// Constructor (Construiese un arbore de sufixe ale textului dat)
  30. SuffixTrie(string s)
  31. {
  32. root = new SuffixTrieNode();
  33.  
  34. /// Sunt luate in considerare toate sufixele sirului dat si le insereaza
  35. /// in arborele de sufixe folosind functia recursiva
  36. /// insertSuffix() din clasa SuffixTrieNode
  37. for (int i = 0; i < s.length(); i++)
  38. root->insertSuffix(s.substr(i));
  39. }
  40.  
  41. /// Metoda pentru numararea tuturor nodurilor din arborele de sufixe
  42. int countNodesInTrie() { return _countNodesInTrie(root); }
  43. };
  44.  
  45. /// O functie recursiva pentru inserarea unui sufix al lui s
  46. /// in subarborele cu radacina in acest nod
  47. void SuffixTrieNode::insertSuffix(string s)
  48. {
  49. /// Daca sirul are mai multe caractere
  50. if (s.length() > 0)
  51. {
  52. /// Gaseste primul caracter si-l converteste
  53. /// intr-un rang intre 0-25.
  54. char cIndex = s.at(0) - 'a';
  55.  
  56. /// Daca nu exista nici o muchie pentru acest caracter,
  57. /// adaugam o noua muchie
  58. if (children[cIndex] == NULL)
  59. children[cIndex] = new SuffixTrieNode();
  60. /// Reapeleaza pentru urmatorul sufix
  61. children[cIndex]->insertSuffix(s.substr(1));
  62. }
  63. }
  64.  
  65. /// Functia recursiva pentru numararea nodurilor din arbore
  66. int SuffixTrie::_countNodesInTrie(SuffixTrieNode* node)
  67. {
  68. /// Daca au fost prelucrate toate caracterele din model (tipar),
  69. if (node == NULL)
  70. return 0;
  71.  
  72. int count = 0;
  73. for (int i = 0; i < MAX_CHAR; i++)
  74. {
  75. /// Daca fiul este nenul (NULL), atunci gasim numarul tuturor nodurilor
  76. /// din acest subarbore
  77. if (node->children[i] != NULL)
  78. count += _countNodesInTrie(node->children[i]);
  79. }
  80.  
  81. /// Intoarce numarul de noduri din subarbore plus
  82. /// 1 deoarece numaram si numarul propriu al nodului
  83. return (1 + count);
  84. }
  85.  
  86. /// Intoarce numarul de subsiruri distincte din str
  87. int countDistinctSubstring(string str)
  88. {
  89. /// Construieste arborele cu toate sufixele
  90. SuffixTrie sTrie(str);
  91.  
  92. /// Intoarce numarul de noduri din arborele de sufixe
  93. return sTrie.countNodesInTrie();
  94. }
  95.  
  96. /// Programul principal pentru testarea functiei de mai sus
  97. int main()
  98. {
  99. string str = "ababa";
  100. cout << "Numarul de subsiruri distincte este "
  101. << countDistinctSubstring(str);
  102. return 0;
  103. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement