Пример #1
0
 public SnakeWithCharResults( Snake snake, List<CharSnake> charSnakes )
 {
     Snake = snake;
     CharSnakes = charSnakes;
 }
Пример #2
0
        //-----------------------------------------------------------------------------------------
        // MiddleSnake string
        public static SnakePair? MiddleSnake( string[] pa, int a0, int N, string[] pb, int b0, int M, V VForward, V VReverse )
        {
            //int MAX = N + M;
            int MAX = ( N + M ) / 2 + 1;
            int DELTA = N - M;

            VReverse.InitStub( N, M, MAX );

            bool DeltaIsEven = ( DELTA % 2 ) == 0;

            //Debug.WriteLine( "DELTA: " + DELTA + " which is " + ( DeltaIsEven ? "even => checking reverse" : "odd => checking forward" ) );

            for ( int d = 0 ; d <= MAX ; d++ )
            {
                // forward
                // checks against reverse D-1
                for ( int k = -d ; k <= d ; k += 2 )
                {
                    bool down = ( k == -d || ( k != d && VForward[ k - 1 ] < VForward[ k + 1 ] ) );

                    int xStart = down ? VForward[ k + 1 ] : VForward[ k - 1 ];
                    int yStart = xStart - ( down ? k + 1 : k - 1 );

                    int xEnd = down ? xStart : xStart + 1;
                    int yEnd = xEnd - k;

                    int snake = 0;
                    while ( xEnd < N && yEnd < M && pa[ xEnd + a0 ] == pb[ yEnd + b0 ] ) { xEnd++; yEnd++; snake++; }

                    VForward[ k ] = xEnd;

                    // if Δ is odd and k ϵ [ Δ - ( D - 1 ), Δ + ( D - 1 ) ]
                    if ( DeltaIsEven || k < DELTA - ( d - 1 ) || k > DELTA + ( d - 1 ) ) continue;

                    // if the path overlaps the furthest reaching reverse ( D - 1 )-path in diagonal k
                    if ( VForward[ k ] < VReverse[ k ] ) continue;

                    // overlap :)
                    var forward = new Snake( a0, N, b0, M, true, xStart + a0, yStart + b0, down, snake );
                    //Debug.WriteLine( "D:"  + d + " - " + forward );
                    return new SnakePair { D = d, Forward = forward };
                }

                // backward
                // checks against forward D
                for ( int k = -d + DELTA ; k <= d + DELTA ; k += 2 )
                {
                    bool up = ( k == d + DELTA || ( k != -d + DELTA && VReverse[ k - 1 ] < VReverse[ k + 1 ] ) );

                    int xStart = up ? VReverse[ k - 1 ] : VReverse[ k + 1 ];
                    int yStart = xStart - ( up ? k - 1 : k + 1 );

                    int xEnd = up ? xStart : xStart - 1;
                    int yEnd = xEnd - k;

                    int snake = 0;
                    while ( xEnd > 0 && yEnd > 0 && pa[ xEnd + a0 - 1 ] == pb[ yEnd + b0 - 1 ] ) { xEnd--; yEnd--; snake++; }

                    VReverse[ k ] = xEnd;

                    // remember: our k is actually k + Δ

                    // if Δ is even and k + Δ ϵ [ -D, D ]
                    if ( !DeltaIsEven || k < -d || k > d ) continue;

                    // if the path overlaps the furthest reaching forward D-path in diagonal k + Δ
                    if ( VReverse[ k ] > VForward[ k ] ) continue;

                    // overlap :)
                    var reverse = new Snake( a0, N, b0, M, false, xStart + a0, yStart + b0, up, snake );
                    //Debug.WriteLine( "D:" + d + " - " + reverse );
                    if ( d == 1 && ( xEnd != 0 || yEnd != 0 ) )
                    {
                        var forward = new Snake( a0, N, b0, M, true, 0, VForward, k, d, pa, pb );
                        return new SnakePair { D = d, Reverse = reverse, Forward = forward };
                    }
                    return new SnakePair { D = d, Reverse = reverse };
                }
            }

            return null;
        }
Пример #3
0
        //-----------------------------------------------------------------------------------------
        // MergeSnakes
        static IList<Snake> MergeSnakes( IList<Snake> snakes, int a0, int N, int b0, int M )
        {
            var r = new List<Snake>( snakes.Count );

            var c = new Snake( a0, N, b0, M, true, 0, 0, 0, 0, 0 );

            foreach ( var s in snakes )
            {
                if ( s.IsForward )
                {
                    if ( ( s.ADeleted > 0 || s.BInserted > 0 ) && c.DiagonalLength > 0 )
                    {
                        r.Add( c );
                        c = new Snake( a0, N, b0, M, true, c.XEnd, c.YEnd, 0, 0, 0 );
                    }

                    c.ADeleted += s.ADeleted;
                    c.BInserted += s.BInserted;
                    c.DiagonalLength += s.DiagonalLength;

                    Debug.Assert( c.EndPoint == s.EndPoint );
                }
                else
                {
                    c.DiagonalLength += s.DiagonalLength;

                    if ( ( s.ADeleted > 0 || s.BInserted > 0 ) && c.DiagonalLength > 0 )
                    {
                        r.Add( c );
                        c = new Snake( a0, N, b0, M, true, c.XEnd, c.YEnd, 0, 0, 0 );
                    }

                    c.ADeleted += s.ADeleted;
                    c.BInserted += s.BInserted;

                    Debug.Assert( c.EndPoint == s.StartPoint );
                }
            }

            if ( c.StartPoint != c.EndPoint ) r.Add( c );

            return r;
        }
Пример #4
0
        static void Compare( int recursion, List<Snake> snakes,
			string[] pa, int a0, int N, string[] pb, int b0, int M,
			V VForward, V VReverse )
        {
            //Debug.WriteLine( new String( '-', recursion ) + recursion + "> Compare( " + a0 + ", " + b0 + " ) + ( " + N + ", " + M + " ) = ( " + ( a0 + N ) + ", " + ( b0 + M ) + " )" );

            if ( N == 0 && M > 0 )
            {
                var down = new Snake( a0, N, b0, M, true, a0, b0, 0, M, 0 );
                //Debug.WriteLine( "down: " + down );
                snakes.Add( down );
            }

            if ( M == 0 && N > 0 )
            {
                var right = new Snake( a0, N, b0, M, true, a0, b0, N, 0, 0 );
                //Debug.WriteLine( "right: " + right );
                snakes.Add( right );
            }

            if ( N <= 0 || M <= 0 ) return;

            SnakePair? middle = null;

            VForward[ 1 ] = 0;
            //VReverse[ N - M - 1 ] = N;

            middle = DiffCommon.CalcForD.MiddleSnake( pa, a0, N, pb, b0, M, VForward, VReverse );

            if ( middle == null ) throw new ApplicationException( "No middle snake" );

            var m = middle.Value;
            int d = middle.Value.D;

            //Debug.WriteLine( "d:" + d + " " + m.Forward + " " + m.Reverse );

            if ( d > 1 )
            {
                var xy = ( m.Forward != null ? m.Forward.StartPoint : m.Reverse.EndPoint );
                var uv = ( m.Reverse != null ? m.Reverse.StartPoint : m.Forward.EndPoint );

                Compare( recursion + 1, snakes, pa, a0, xy.X - a0, pb, b0, xy.Y - b0, VForward, VReverse );

                if ( m.Forward != null ) snakes.Add( m.Forward );
                if ( m.Reverse != null ) snakes.Add( m.Reverse );

                Compare( recursion + 1, snakes, pa, uv.X, a0 + N - uv.X, pb, uv.Y, b0 + M - uv.Y, VForward, VReverse );

            }
            else
            {
                if ( m.Forward != null && m.Reverse != null ) // check for overlapping diagonal
                    if ( m.Forward.XMid - m.Forward.YMid == m.Reverse.XMid - m.Reverse.YMid )
                    {
                        m.Forward.DiagonalLength = m.Reverse.XMid - m.Forward.XMid;
                        m.Reverse.DiagonalLength = 0;
                    }

                if ( m.Forward != null )
                {
                    // D0
                    if ( m.Forward.XStart > a0 )
                    {
                        if ( m.Forward.XStart - a0 != m.Forward.YStart - b0 ) throw new ApplicationException( "Missed D0 forward" );
                        snakes.Add( new Snake( a0, N, b0, M, true, a0, b0, 0, 0, m.Forward.XStart - a0 ) );
                    }

                    snakes.Add( m.Forward );
                }

                if ( m.Reverse != null )
                {
                    snakes.Add( m.Reverse );

                    // D0
                    if ( m.Reverse.XStart < a0 + N )
                    {
                        if ( a0 + N - m.Reverse.XStart != b0 + M - m.Reverse.YStart ) throw new ApplicationException( "Missed D0 reverse" );
                        snakes.Add( new Snake( a0, N, b0, M, true, m.Reverse.XStart, m.Reverse.YStart, 0, 0, a0 + N - m.Reverse.XStart ) );
                    }
                }
            }
        }
Пример #5
0
        static SnakeWithCharResults ConvertToLines( CompareCharsData data, bool deleted, IList<Snake> chars, Snake lineSnake )
        {
            //Debug.WriteLine( "\nConvertToLines " + ( deleted ? "DELETED" : "INSERTED" ) );
            //Debug.WriteLine( data.ToString() );

            var list = new List<CharSnake>();

            foreach ( var s in chars )
            {
                //Debug.WriteLine( "Char " + s );

                int lStart, cStart, lMid, cMid, lEnd, cEnd;
                data.LineFromChar( deleted ? s.XStart : s.YStart, out lStart, out cStart );
                data.LineFromChar( deleted ? s.XMid : s.YMid, out lMid, out cMid );
                data.LineFromChar( deleted ? s.XEnd : s.YEnd, out lEnd, out cEnd );

                //Debug.WriteLine( "LINE:CHAR Start: " + lStart + ":" + cStart + " Mid: " + lMid + ":" + cMid + " End:" + lEnd + ":" + cEnd );

                if ( deleted ? s.ADeleted > 0 : s.BInserted > 0 )
                {
                    for ( int l = lStart ; l <= lMid ; l++ )
                    {
                        var cs = new CharSnake();
                        cs.Line = l;
                        cs.IsDeleted = deleted;
                        cs.CharStart = ( l == lStart ? cStart : 0 );
                        var end = ( l == lMid ? cMid : data.LineLength( l ) );
                        cs.Diff = end - cs.CharStart;
                        cs.IsEOL = data.IsEOL( l, end );

                        //Debug.WriteLine( "Diff " + cs + " = '" + data.Substring( cs.CharStart, cs.Diff ) + "'" );

                        if ( cs.Diff > 0 || data.LineLength( l ) == 0 ) list.Add( cs );
                    }
                }

                if ( s.DiagonalLength > 0 )
                {
                    for ( int l = lMid ; l <= lEnd ; l++ )
                    {
                        var cs = new CharSnake();
                        cs.Line = l;
                        cs.IsDeleted = deleted;
                        cs.CharStart = ( l == lMid ? cMid : 0 );
                        var end = ( l == lEnd ? cEnd : data.LineLength( l ) );
                        cs.Same = end - cs.CharStart;
                        cs.IsEOL = data.IsEOL( l, end );

                        //Debug.WriteLine( "Same " + cs + " = '" + data.Substring( cs.CharStart, cs.Same ) + "'" );

                        if ( cs.Same > 0 || data.LineLength( l ) == 0 ) list.Add( cs );
                    }
                }
            }

            return new SnakeWithCharResults( lineSnake, list );
        }