levenshteinMatrice.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #pragma once
  2. #include <iostream>
  3. #include <map>
  4. #include "jsonContainer.hh"
  5. #include "levenshtein.hpp"
  6. enum eLevenshteinOperator: char
  7. {
  8. add = '+',
  9. rem = '-',
  10. mod = '!',
  11. equ = '='
  12. };
  13. class LevenshteinMatrice_base
  14. {
  15. public:
  16. virtual ~LevenshteinMatrice_base() {}
  17. const std::map<const JSonElement*, eLevenshteinOperator> path() const;
  18. virtual size_t result() const =0;
  19. virtual void debug(std::ostream &out) const =0;
  20. public:
  21. class Builder
  22. {
  23. public:
  24. Builder();
  25. ~Builder();
  26. const LevenshteinMatrice_base *build(const JSonElement *a, const JSonElement *b) const;
  27. };
  28. protected:
  29. std::map<const JSonElement*, eLevenshteinOperator> operations;
  30. };
  31. class LevenshteinMatrice_manual: public LevenshteinMatrice_base
  32. {
  33. public:
  34. LevenshteinMatrice_manual *add(const JSonElement*, eLevenshteinOperator);
  35. size_t result() const;
  36. void debug(std::ostream &out) const;
  37. public:
  38. size_t _result;
  39. };
  40. template<typename T>
  41. class LevenshteinMatrice: public LevenshteinMatrice_base
  42. {
  43. public:
  44. LevenshteinMatrice(const JSonContainer::const_iterator aBegin, const JSonContainer::const_iterator aEnd,
  45. const JSonContainer::const_iterator bBegin, const JSonContainer::const_iterator bEnd,
  46. size_t n, size_t m)
  47. {
  48. size_t i, j;
  49. JSonContainer::const_iterator a = aBegin;
  50. JSonContainer::const_iterator b;
  51. this->n = n;
  52. this->m = m;
  53. this->matrice = new T*[n +1]();
  54. this->subMatrice = new LevenshteinMatrice_base**[n +1]();
  55. matrice[0] = new T[m +1];
  56. for (i =1; i <= m; ++i)
  57. matrice[0][i] = i;
  58. for (i=1; i <= n; ++i)
  59. {
  60. matrice[i] = new T[m +1];
  61. matrice[i][0] = i;
  62. }
  63. for (i=0; i <= n; ++i)
  64. {
  65. subMatrice[i] = new LevenshteinMatrice_base*[m +1];
  66. for (size_t j=0; j <= m; ++j)
  67. subMatrice[i][j] = nullptr;
  68. }
  69. for (i =1; a != aEnd; ++i, ++a)
  70. {
  71. b = bBegin;
  72. for (j =1; b != bEnd; ++j, ++b)
  73. {
  74. //TODO compute submatrice
  75. /*
  76. matrice[i][j] = std::min(std::min(
  77. get(i -1, j) +1,
  78. get(i, j -1) +1),
  79. get(i -1, j -1) + ((levenshteinCompare(*a, *b) > LEVENSHTEIN_SENSIBILITY) ? 0 : 1)); // TODO set submatrice
  80. */
  81. matrice[i][j] = std::min(
  82. get(i -1, j) +1,
  83. get(i, j -1) +1);
  84. }
  85. }
  86. };
  87. ~LevenshteinMatrice()
  88. {
  89. for (size_t i=0; i <= n; ++i)
  90. {
  91. delete []matrice[i];
  92. for (size_t j=0; j <= m; ++j)
  93. if (subMatrice[i][j])
  94. delete subMatrice[i][j];
  95. delete []subMatrice[i];
  96. }
  97. delete []matrice;
  98. delete []subMatrice;
  99. };
  100. void prune()
  101. {
  102. //TODO
  103. }
  104. T get(size_t a, size_t b) const
  105. {
  106. return matrice[a][b];
  107. };
  108. std::list<eLevenshteinOperator> shortestPath() const
  109. {
  110. std::list<eLevenshteinOperator> result;
  111. size_t i = n;
  112. size_t j = m;
  113. while (i || j)
  114. {
  115. if (i && (!j || matrice[i][j] > matrice[i-1][j]))
  116. {
  117. result.push_front(eLevenshteinOperator::add);
  118. --i;
  119. }
  120. else if (j && (!i || matrice[i][j] > matrice[i][j -1]))
  121. {
  122. result.push_front(eLevenshteinOperator::rem);
  123. --j;
  124. }
  125. else if (i && j)
  126. {
  127. result.push_front(matrice[i][j] == matrice[i-1][j-1] ? eLevenshteinOperator::equ : eLevenshteinOperator::mod);
  128. --i;
  129. --j;
  130. }
  131. else if (i)
  132. {
  133. result.push_front(eLevenshteinOperator::add);
  134. --i;
  135. }
  136. else if (j)
  137. {
  138. result.push_front(eLevenshteinOperator::rem);
  139. --j;
  140. }
  141. }
  142. return result;
  143. }
  144. void debug(std::ostream &o) const
  145. {
  146. for (size_t i =0; i <= n; ++i)
  147. {
  148. for (size_t j=0; j <= m; ++j)
  149. o << (int) (matrice[n][m]) << '\t';
  150. o << std::endl;
  151. }
  152. }
  153. size_t result() const
  154. {
  155. return (size_t) matrice[n][m];
  156. };
  157. private:
  158. T **matrice;
  159. /**
  160. * Usefull only on `modify' operation
  161. **/
  162. LevenshteinMatrice_base ***subMatrice;
  163. size_t n;
  164. size_t m;
  165. };