From 7de0fdad3c791c6938520653a5c61fb8edbc67dc Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Sat, 11 Sep 2021 14:51:45 +0200 Subject: [PATCH] DocDiff application: Finish LCS algorithm --- Pdf4QtLib/sources/pdfalgorithmlcs.h | 76 +++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/Pdf4QtLib/sources/pdfalgorithmlcs.h b/Pdf4QtLib/sources/pdfalgorithmlcs.h index 90fa190..1e55925 100644 --- a/Pdf4QtLib/sources/pdfalgorithmlcs.h +++ b/Pdf4QtLib/sources/pdfalgorithmlcs.h @@ -37,8 +37,21 @@ public: Iterator it2End, Comparator comparator); + struct SequenceItem + { + size_t index1 = std::numeric_limits::max(); + size_t index2 = std::numeric_limits::max(); + + bool isLeftValid() const { return index1 == std::numeric_limits::max(); } + bool isRightValid() const { return index2 == std::numeric_limits::max(); } + bool isMatch() const { return isLeftValid() && isRightValid(); } + }; + using Sequence = std::vector; + void perform(); + const Sequence& getSequence() const { return m_sequence; } + private: Iterator m_it1; Iterator m_it1End; @@ -52,6 +65,7 @@ private: Comparator m_comparator; std::vector m_backtrackData; + Sequence m_sequence; }; template @@ -119,6 +133,68 @@ void PDFAlgorithmLongestCommonSubsequence::perform() // Bottom row will become top row std::swap(rowTop, rowBottom); } + + size_t i1 = m_size1 - 1; + size_t i2 = m_size2 - 1; + + while (i1 > 0 && i2 > 0) + { + SequenceItem item; + + const size_t index1 = i1 - 1; + const size_t index2 = i2 - 1; + + auto it1 = std::next(m_it1, index1); + auto it2 = std::next(m_it2, index2); + + if (m_comparator(*it1, *it2)) + { + item.index1 = index1; + item.index2 = index2; + + --i1; + --i2; + } + else + { + if (m_backtrackData[i2 * m_size1 + i1]) + { + item.index1 = index1; + --i1; + } + else + { + item.index2 = index2; + --i2; + } + } + + m_sequence.push_back(item); + } + + while (i1 > 0) + { + SequenceItem item; + + const size_t index1 = i1 - 1; + item.index1 = index1; + --i1; + + m_sequence.push_back(item); + } + + while (i2 > 0) + { + SequenceItem item; + + const size_t index2 = i2 - 1; + item.index2 = index2; + --i2; + + m_sequence.push_back(item); + } + + std::reverse(m_sequence.begin(), m_sequence.end()); } } // namespace pdf