lcs_via_lis.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #pragma once
  2. #include <library/cpp/containers/paged_vector/paged_vector.h>
  3. #include <util/generic/ptr.h>
  4. #include <util/generic/hash.h>
  5. #include <util/generic/vector.h>
  6. #include <util/generic/algorithm.h>
  7. #include <util/memory/pool.h>
  8. namespace NLCS {
  9. template <typename TVal>
  10. struct TLCSCtx {
  11. typedef TVector<ui32> TSubsequence;
  12. typedef THashMap<TVal, TSubsequence, THash<TVal>, TEqualTo<TVal>, ::TPoolAllocator> TEncounterIndex;
  13. typedef TVector<std::pair<ui32, ui32>> TLastIndex;
  14. typedef NPagedVector::TPagedVector<TSubsequence, 4096> TCover;
  15. TMemoryPool Pool;
  16. THolder<TEncounterIndex> Encounters;
  17. TLastIndex LastIndex;
  18. TCover Cover;
  19. TSubsequence ResultBuffer;
  20. TLCSCtx()
  21. : Pool(16 * 1024 - 64, TMemoryPool::TExpGrow::Instance())
  22. {
  23. Reset();
  24. }
  25. void Reset() {
  26. Encounters.Reset(nullptr);
  27. Pool.Clear();
  28. Encounters.Reset(new TEncounterIndex(&Pool));
  29. LastIndex.clear();
  30. Cover.clear();
  31. ResultBuffer.clear();
  32. }
  33. };
  34. namespace NPrivate {
  35. template <typename TIt, typename TVl>
  36. struct TSequence {
  37. typedef TIt TIter;
  38. typedef TVl TVal;
  39. const TIter Begin;
  40. const TIter End;
  41. const size_t Size;
  42. TSequence(TIter beg, TIter end)
  43. : Begin(beg)
  44. , End(end)
  45. , Size(end - beg)
  46. {
  47. }
  48. };
  49. template <typename TVal, typename TSequence, typename TResult>
  50. size_t MakeLCS(TSequence s1, TSequence s2, TResult* res = nullptr, TLCSCtx<TVal>* ctx = nullptr) {
  51. typedef TLCSCtx<TVal> TCtx;
  52. THolder<TCtx> ctxhld;
  53. if (!ctx) {
  54. ctxhld.Reset(new TCtx());
  55. ctx = ctxhld.Get();
  56. } else {
  57. ctx->Reset();
  58. }
  59. size_t maxsize = Max(s1.Size, s2.Size);
  60. auto& index = *(ctx->Encounters);
  61. for (auto it = s1.Begin; it != s1.End; ++it) {
  62. index[*it];
  63. }
  64. for (auto it = s2.Begin; it != s2.End; ++it) {
  65. auto hit = index.find(*it);
  66. if (hit != index.end()) {
  67. hit->second.push_back(it - s2.Begin);
  68. }
  69. }
  70. if (!res) {
  71. auto& lastindex = ctx->ResultBuffer;
  72. lastindex.reserve(maxsize);
  73. for (auto it1 = s1.Begin; it1 != s1.End; ++it1) {
  74. const auto& sub2 = index[*it1];
  75. for (auto it2 = sub2.rbegin(); it2 != sub2.rend(); ++it2) {
  76. ui32 x = *it2;
  77. auto lit = LowerBound(lastindex.begin(), lastindex.end(), x);
  78. if (lit == lastindex.end()) {
  79. lastindex.push_back(x);
  80. } else {
  81. *lit = x;
  82. }
  83. }
  84. }
  85. return lastindex.size();
  86. } else {
  87. auto& lastindex = ctx->LastIndex;
  88. auto& cover = ctx->Cover;
  89. lastindex.reserve(maxsize);
  90. for (auto it1 = s1.Begin; it1 != s1.End; ++it1) {
  91. const auto& sub2 = index[*it1];
  92. for (auto it2 = sub2.rbegin(); it2 != sub2.rend(); ++it2) {
  93. ui32 x = *it2;
  94. auto lit = LowerBound(lastindex.begin(), lastindex.end(), std::make_pair(x, (ui32)0u));
  95. if (lit == lastindex.end()) {
  96. lastindex.push_back(std::make_pair(x, cover.size()));
  97. cover.emplace_back();
  98. cover.back().push_back(x);
  99. } else {
  100. *lit = std::make_pair(x, lit->second);
  101. cover[lit->second].push_back(x);
  102. }
  103. }
  104. }
  105. if (cover.empty()) {
  106. return 0;
  107. }
  108. std::reverse(cover.begin(), cover.end());
  109. auto& resbuf = ctx->ResultBuffer;
  110. resbuf.push_back(cover.front().front());
  111. for (auto it = cover.begin() + 1; it != cover.end(); ++it) {
  112. auto pit = UpperBound(it->begin(), it->end(), resbuf.back(), std::greater<ui32>());
  113. Y_ABORT_UNLESS(pit != it->end(), " ");
  114. resbuf.push_back(*pit);
  115. }
  116. std::reverse(resbuf.begin(), resbuf.end());
  117. for (auto it = resbuf.begin(); it != resbuf.end(); ++it) {
  118. res->push_back(*(s2.Begin + *it));
  119. }
  120. return lastindex.size();
  121. }
  122. }
  123. }
  124. template <typename TVal, typename TIter, typename TResult>
  125. size_t MakeLCS(TIter beg1, TIter end1, TIter beg2, TIter end2, TResult* res = nullptr, TLCSCtx<TVal>* ctx = nullptr) {
  126. typedef NPrivate::TSequence<TIter, TVal> TSeq;
  127. size_t sz1 = end1 - beg1;
  128. size_t sz2 = end2 - beg2;
  129. if (sz2 > sz1) {
  130. DoSwap(beg1, beg2);
  131. DoSwap(end1, end2);
  132. DoSwap(sz1, sz2);
  133. }
  134. return NPrivate::MakeLCS<TVal>(TSeq(beg1, end1), TSeq(beg2, end2), res, ctx);
  135. }
  136. template <typename TVal, typename TColl, typename TRes>
  137. size_t MakeLCS(const TColl& coll1, const TColl& coll2, TRes* res = nullptr, TLCSCtx<TVal>* ctx = nullptr) {
  138. return MakeLCS<TVal>(coll1.begin(), coll1.end(), coll2.begin(), coll2.end(), res, ctx);
  139. }
  140. template <typename TVal, typename TIter>
  141. size_t MeasureLCS(TIter beg1, TIter end1, TIter beg2, TIter end2, TLCSCtx<TVal>* ctx = nullptr) {
  142. return MakeLCS<TVal>(beg1, end1, beg2, end2, (TVector<TVal>*)nullptr, ctx);
  143. }
  144. template <typename TVal, typename TColl>
  145. size_t MeasureLCS(const TColl& coll1, const TColl& coll2, TLCSCtx<TVal>* ctx = nullptr) {
  146. return MeasureLCS<TVal>(coll1.begin(), coll1.end(), coll2.begin(), coll2.end(), ctx);
  147. }
  148. }