Example #1
0
        /// <summary>Compare two sequences and identify a list of edits between them.</summary>
        /// <remarks>Compare two sequences and identify a list of edits between them.</remarks>
        /// <?></?>
        /// <param name="cmp">the comparator supplying the element equivalence function.</param>
        /// <param name="a">
        /// the first (also known as old or pre-image) sequence. Edits
        /// returned by this algorithm will reference indexes using the
        /// 'A' side:
        /// <see cref="Edit.GetBeginA()">Edit.GetBeginA()</see>
        /// ,
        /// <see cref="Edit.GetEndA()">Edit.GetEndA()</see>
        /// .
        /// </param>
        /// <param name="b">
        /// the second (also known as new or post-image) sequence. Edits
        /// returned by this algorithm will reference indexes using the
        /// 'B' side:
        /// <see cref="Edit.GetBeginB()">Edit.GetBeginB()</see>
        /// ,
        /// <see cref="Edit.GetEndB()">Edit.GetEndB()</see>
        /// .
        /// </param>
        /// <returns>
        /// a modifiable edit list comparing the two sequences. If empty, the
        /// sequences are identical according to
        /// <code>cmp</code>
        /// 's rules. The
        /// result list is never null.
        /// </returns>
        public virtual EditList Diff <S>(SequenceComparator <S> cmp, S a, S b) where
        S : Sequence
        {
            Edit region = cmp.ReduceCommonStartEnd(a, b, CoverEdit(a, b));

            switch (region.GetType())
            {
            case Edit.Type.INSERT:
            case Edit.Type.DELETE:
            {
                return(EditList.Singleton(region));
            }

            case Edit.Type.REPLACE:
            {
                SubsequenceComparator <S> cs  = new SubsequenceComparator <S>(cmp);
                Subsequence <S>           @as = Subsequence <S> .A(a, region);

                Subsequence <S> bs = Subsequence <S> .B(b, region);

                EditList e = Subsequence <S> .ToBase(DiffNonCommon(cs, @as, bs), @as, bs);

                // The last insertion may need to be shifted later if it
                // inserts elements that were previously reduced out as
                // common at the end.
                //
                Edit last = e[e.Count - 1];
                if (last.GetType() == Edit.Type.INSERT)
                {
                    while (last.endB < b.Size() && cmp.Equals(b, last.beginB, b, last.endB))
                    {
                        last.beginA++;
                        last.endA++;
                        last.beginB++;
                        last.endB++;
                    }
                }
                return(e);
            }

            case Edit.Type.EMPTY:
            {
                return(new EditList(0));
            }

            default:
            {
                throw new InvalidOperationException();
            }
            }
        }
Example #2
0
 public override bool Equals(Subsequence <S> a, int ai, Subsequence <S> b, int bi)
 {
     return(cmp.Equals(a.@base, ai + a.begin, b.@base, bi + b.begin));
 }
 public override bool Equals(HashedSequence <S> a, int ai, HashedSequence <S> b, int
                             bi)
 {
     //
     return(a.hashes[ai] == b.hashes[bi] && cmp.Equals(a.@base, ai, b.@base, bi));
 }