private static void MergeCandidate(List<CandidateRec> K, ref int k, int i, EquivalenceClass[] E, int p) { int r = 0; CandidateRec c = K[0]; do { int j = E[p].Number; int s = -1; for (int l = r; l <= k; l++) { if (K[l].b < j && K[l + 1].b > j) { s = l; break; } } if (s >= 0) { if (K[s + 1].b > j) { K[r] = c; r = s + 1; c = new CandidateRec() { a = i, b = j, prev = K[s] }; } if (s == k) { K.Add(K[k + 1]); k = k + 1; break; } } if (E[p].Last) { break; } else { p = p + 1; } } while (true); K[r] = c; }
private static int[] CreateLastCommonSubsequency(List<string> O, List<string> A) { int m = O.Count; int n = A.Count; char[] ignore = new char[] { ' ', '\t' }; List<LineHash> V = new List<LineHash>(n); V.AddRange(A.Select((x, i) => new LineHash() { Number = i + 1, Line = x.DiffHash(ignore) })); V.Sort((x, y) => { int r = x.Line.CompareTo(y.Line); if (r == 0) { r = x.Number.CompareTo(y.Number); } return r; }); EquivalenceClass[] E = new EquivalenceClass[n + 1]; E[0] = new EquivalenceClass() { Number = 0, Last = true }; for (int j = 1; j < n; j++) { E[j] = new EquivalenceClass() { Number = V[j - 1].Number, Last = V[j - 1].Line.CompareTo(V[j].Line) != 0 }; } E[n] = new EquivalenceClass() { Number = V[n - 1].Number, Last = true }; int[] P = new int[m]; for (int i = 0; i < m; i++) { string key = O[i].DiffHash(ignore); int j = V.FindIndex(x => x.Line.CompareTo(key) == 0); if (j >= 0 && E[j].Last) { P[i] = j + 1; } else { P[i] = 0; } } List<CandidateRec> K = new List<CandidateRec>(); K.Add(new CandidateRec() { a = 0, b = 0, prev = null }); K.Add(new CandidateRec() { a = m + 1, b = n + 1, prev = null }); int k = 0; for (int i = 0; i < m; i++) { if (P[i] != 0) { MergeCandidate(K, ref k, i + 1, E, P[i]); } } int[] J = new int[m + 1]; for (int i = 0; i <= m; i++) { J[i] = 0; } CandidateRec c = K[k]; do { J[c.a] = c.b; c = c.prev; } while (c != null); for (int i = 0; i < m; i++) { int j = J[i + 1]; if (j != 0 && O[i].DiffHash(ignore).CompareTo(A[j - 1].DiffHash(ignore)) != 0) { J[i + 1] = 0; } } return J; }