#pragma once #include #include #include #include "jsonElement.hh" #include "levenshteinMatrice.hpp" #define LEVENSHTEIN_SENSIBILITY (0.7f) float levenshteinPercent(const std::string &a, const std::string &b); template float levenshteinPercent(const std::list *a, const std::list *b); bool levenshteinStrictCompare(const char &a, const char &b); bool levenshteinStrictCompare(const JSonElement *a, const JSonElement *b); bool levenshteinCompare(const char &a, const char &b); bool levenshteinCompare(const JSonElement *a, const JSonElement *b); template static LevenshteinMatrice *_levenshteinMatrice(const ITERATOR &aBegin, const ITERATOR &aEnd, const ITERATOR &bBegin, const ITERATOR &bEnd, const size_t lenA, const size_t lenB) { size_t i, j; LevenshteinMatrice *matrice = new LevenshteinMatrice(lenA, lenB); ITERATOR a = aBegin; ITERATOR b; for (i =1; a != aEnd; ++i, ++a) { b = bBegin; for (j =1; b != bEnd; ++j, ++b) matrice->set(i, j, std::min(std::min( matrice->get(i -1, j) +1, matrice->get(i, j -1) +1), matrice->get(i -1, j -1) + ((levenshteinCompare(*a, *b) > LEVENSHTEIN_SENSIBILITY) ? 0 : 1))); } return matrice; }; template static float _levenshteinPercent(ITERATOR aBegin, ITERATOR aEnd, ITERATOR bBegin, ITERATOR bEnd, size_t lenA, size_t lenB) { const size_t maxSize = std::max(lenA, lenB); while (aBegin != aEnd && bBegin != bEnd && levenshteinCompare(*aBegin, *bBegin)) { aBegin++; bBegin++; lenA--; lenB--; } if (!lenA && !lenB) return 1.f; if (!lenA) return (float) lenB / maxSize; if (!lenB) return (float) lenA / maxSize; LevenshteinMatrice *matrice = _levenshteinMatrice(aBegin, aEnd, bBegin, bEnd, lenA, lenB); const SIZE result = matrice->result(); delete matrice; return 1 - ((float)result / maxSize); }; template float levenshteinPercent(const std::list *a, const std::list *b) { const size_t lenA = a->size(); const size_t lenB = b->size(); typename std::list::const_iterator aBegin = a->cbegin(); typename std::list::const_iterator aEnd = a->cend(); typename std::list::const_iterator bBegin = b->cbegin(); typename std::list::const_iterator bEnd = b->cend(); if (lenA < UCHAR_MAX && lenB < UCHAR_MAX) return _levenshteinPercent::const_iterator, T *>(aBegin, aEnd, bBegin, bEnd, lenA, lenB); if (lenA < USHRT_MAX && lenB < USHRT_MAX) return _levenshteinPercent::const_iterator, T *>(aBegin, aEnd, bBegin, bEnd, lenA, lenB); return _levenshteinPercent::const_iterator, T *>(aBegin, aEnd, bBegin, bEnd, lenA, lenB); } template LevenshteinMatrice_base *levenshteinShortestPath(const std::list *a, const std::list *b) { const size_t lenA = a->size(); const size_t lenB = b->size(); if (lenA < UCHAR_MAX && lenB < UCHAR_MAX) return _levenshteinMatrice::const_iterator, T *>(a->cbegin(), a->cend(), b->cbegin(), b->cend(), lenA, lenB); if (lenA < USHRT_MAX && lenB < USHRT_MAX) return _levenshteinMatrice::const_iterator, T *>(a->cbegin(), a->cend(), b->cbegin(), b->cend(), lenA, lenB); return _levenshteinMatrice::const_iterator, T *>(a->cbegin(), a->cend(), b->cbegin(), b->cend(), lenA, lenB); }