Exemplo n.º 1
0
        protected override string DoCompare <T>(IList <T> src, IList <T> dst, Comparison <T> comp)
        {
            var sn = src.Count;
            var dn = dst.Count;

            while (sn > 0 && dn > 0 && comp(src[sn - 1], dst[dn - 1]) == 0)
            {
                --sn;
                --dn;
            }
            if (sn == 0)
            {
                return(new StringBuilder(dst.Count).Append('A', dn).Append('C', src.Count).ToString());
            }
            if (dn == 0)
            {
                return(new StringBuilder(src.Count).Append('D', sn).Append('C', dst.Count).ToString());
            }

            var heads = new Head[sn + dn + 3];
            var z     = heads.Length - 2;
            var orig  = sn + 1;
            var goal  = dn + 1;

            heads[orig].Tra = null;

            for (var i = 1; i < z; i++)
            {
                var min = orig - i + 1;
                var max = orig + i - 1;
                for (var p = min; p <= max; p += 2)
                {
                    if (p < 1 || p > z)
                    {
                        continue;
                    }

                    var s = heads[p].Src;
                    var d = heads[p].Dst;
                    var r = heads[p].Tra;

                    // Find a snake.
                    var u = 0;
                    while (s + u < sn && d + u < dn && comp(src[s + u], dst[d + u]) == 0)
                    {
                        u++;
                    }
                    if (u > 0)
                    {
                        s += u;
                        d += u;
                        r += Trace.C(u);
                    }

                    // Recognize a difference.
                    if (heads[p - 1].Src + heads[p - 1].Dst <= s + d)
                    {
                        heads[p - 1].Src = s + 1;
                        heads[p - 1].Dst = d;
                        heads[p - 1].Tra = r + Trace.D;
                    }
                    if (heads[p + 1].Src + heads[p + 1].Dst <= s + d)
                    {
                        heads[p + 1].Src = s;
                        heads[p + 1].Dst = d + 1;
                        heads[p + 1].Tra = r + Trace.A;
                    }
                }

                // See if we have reached the goal.
                if (heads[goal].Src >= sn && heads[goal].Dst >= dn)
                {
                    int posts = src.Count - sn;
                    return(heads[goal].Tra.ToStringBuilder(posts).Append('C', posts).ToString());
                }
            }

            throw new ApplicationException("Edit matrix overrun.  It means this program has a bug in it.");
        }