WikiFunctions.Diff._longestCommonSubsequence C# (CSharp) Method

_longestCommonSubsequence() private method

private _longestCommonSubsequence ( IList a, IList b ) : System.Collections.Generic.List
a IList
b IList
return System.Collections.Generic.List
        private IntList _longestCommonSubsequence(IList a, IList b)
        {
            int aStart = 0;
            int aFinish = a.Count - 1;
            IntList matchVector = new IntList();
            Hashtable bMatches;

            // initialize matchVector to length of a
            for (int i = 0; i < a.Count; i++)
                matchVector.Add(-1);

            if (!IsPrepared(out bMatches))
            {
                int bStart = 0;
                int bFinish = b.Count - 1;

                // First we prune off any common elements at the beginning
                while (aStart <= aFinish && bStart <= bFinish && compare(a[aStart], b[bStart]))
                    matchVector[aStart++] = bStart++;

                // now the end
                while (aStart <= aFinish && bStart <= bFinish && compare(a[aFinish], b[bFinish]))
                    matchVector[aFinish--] = bFinish--;

                // Now compute the equivalence classes of positions of elements
                bMatches =
                    _withPositionsOfInInterval(b, bStart, bFinish);
            }

            IntList thresh = new IntList();
            TrioList links = new TrioList();

            for (int i = aStart; i <= aFinish; i++)
            {
                IntList aimatches = (IntList) bMatches[a[i]];
                if (aimatches != null)
                {
                    int k = 0;
                    foreach (int j in aimatches)
                    {
                        // # optimization: most of the time this will be true
                        if (k > 0 && thresh[k] > j && thresh[k - 1] < j)
                            thresh[k] = j;
                        else
                            k = _replaceNextLargerWith(thresh, j, k);

                        // oddly, it's faster to always test this (CPU cache?).
                        if (k != -1)
                        {
                            Trio t = new Trio((Trio) (k > 0 ? links[k - 1] : null), i, j);
                            if (k == links.Count)
                                links.Add(t);
                            else
                                links[k] = t;
                        }
                    }
                }
            }

            if (thresh.Count > 0)
            {
                for (Trio link = (Trio) links[thresh.Count - 1]; link != null; link = link.a)
                    matchVector[link.b] = link.c;
            }

            return matchVector;
        }