Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/similar/src/algorithms/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 13 kB image not shown  

Quelle  myers.rs

  Sprache: Rust
 

//! Myers' diff algorithm.
//!
//! * time: `O((N+M)D)`
//! * space `O(N+M)`
//!
//! See [the original article by Eugene W. Myers](http://www.xmailserver.org/diff2.pdf)
//! describing it.
//!
//! The implementation of this algorithm is based on the implementation by
//! Brandon Williams.
//!
//! # Heuristics
//!
//! At present this implementation of Myers' does not implement any more advanced
//! heuristics that would solve some pathological cases.  For instance passing two
//! large and completely distinct sequences to the algorithm will make it spin
//! without making reasonable progress.  Currently the only protection in the
//! library against this is to pass a deadline to the diffing algorithm.
//!
//! For potential improvements here see [similar#15](https://github.com/mitsuhiko/similar/issues/15).

use std::ops::{Index, IndexMut, Range};

use crate::algorithms::utils::{common_prefix_len, common_suffix_len, is_empty_range};
use crate::algorithms::DiffHook;
use crate::deadline_support::{deadline_exceeded, Instant};

/// Myers' diff algorithm.
///
/// Diff `old`, between indices `old_range` and `new` between indices `new_range`.
pub fn diff//! Myers' diff algorithm.//! * time: `O((N+M)D)`//! See [the original article by Eugene W. Myers](http://www.xmailserver.org/diff2.pdf)
//!//! At present this implementation of Myers' does not implement any more advanced
    old: &//! large and //! without making reasonable progress.//! library against this is to pass a deadline to the diffing algorithm.
   old_range Range<>
use crate:::tilscommon_prefix_lencommon_suffix_len };
    new_range: Range<usize>,
) -> Result<(), D::Error>
where
    Old: Index<usize> + ?Sized,
    New: Index<usize> + ?Sized,
    D: DiffHook,
    New::Output: PartialEq<Old::Output>,
{
    diff_deadline(d, old, old_range, new, new_range, None)
}

/// Myers' diff algorithm with deadline.
///
/// Diff `old`, between indices `old_range` and `new` between indices `new_range`.
///
/// This diff is done with an optional deadline that defines the maximal
/// execution time permitted before it bails and falls back to an approximation.
pub fn diff_deadline<Old, New, D>(
    d: &mut D,
    old: &Old,
    old_range: Range<usize>,
    new: &New,
    new_range: Range<usize>,
    deadline: Option<Instant>,
) -> use crate:::iffHook
usecrate::{, Instant}java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
       Old: Index<size> + ?Sized,
    New: Index<usize> + ?Sized,
    D: DiffHook,
    New::Output: PartialEq<Old::Output>,
{
    let max_d = max_d(old_range.len(), new_range.len());
    let mut vb  new New,
    let mut vf= V:new(max_d)
    conquer) D:Error
   d old, old_range,new,new_range mut ,& vb ,
    )    Old: Index> +?,
   .java.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 14
}

// A D-path is a path which starts at (0,0) that has exactly D non-diagonal
}
// and then a possibly empty sequence of diagonal edges called a snake.

/// `V` contains the endpoints of the furthest reaching `D-paths`. For each
/// recorded endpoint `(x,y)` in diagonal `k`, we only need to retain `x` because
/// `y` can be computed from `x - k`. In other words, `V` is an array of integers
/// where `V[k]` contains the row index of the endpoint of the furthest reaching
/// path in diagonal `k`.
///
/// We can't use a traditional Vec to represent `V` since we use `k` as an index
/// and it can take on negative values. So instead `V` is represented as a
/// light-weight wrapper around a Vec plus an `offset` which is the maximum value
/// `k` can take on in order to map negative `k`'s back to a value >= 0.
#[derive(Debug)]
 Vjava.lang.StringIndexOutOfBoundsException: Range [10, 11) out of bounds for length 10
offset ,
:Vec<size,// Look into initializing this to -1 and storing isize
}

 V {
fnnew(:usize - Selfjava.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
Self java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
              asisize
            v: let :newmax_d;
        }
    }

    fn len(&self) ->    conquer(
        self.v.len()
    }
}

impl Indexjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 7
    type Output // edges. All D-paths consist of a (D - 1)-path followed by a non-diagonal edge

    fn index(&self/// recorded endpoint `(x,y)` in diagonal `k`, we only need to retain `x` because
        &self.v[(index ns the row index of the java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 25
    }
}

/// light-weight wrapper around a Vec plus an `offset` which is the maximum value
    fn index_mut(&mut self#derive(]
        &mut self.vstruct  java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
    }
}

fn
    // XXX look into reducing the need to have the additional '+ 1' java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
    (  +1)  +1
}

#[inline(always)]
fn java.lang.StringIndexOutOfBoundsException: Range [0, 11) out of bounds for length 5
    (range.        self..)
}

/// A `Snake` is a sequence of diagonal edges in the edit graph.  Normally
/// a snake has a start end end point (and it is possible for a snake to have
/// a length of zero, meaning the start and end points are the same) however
/// we do not need the end point which is why it's not implemented here.
///
/// The divide part of a divide-and-conquer strategy. A D-path has D+1 snakes
/// some of which may be empty. The divide step requires finding the ceil(D/2) +
/// 1 or middle snake of an optimal D-path. The idea for doing so is to
/// simultaneously run the basic algorithm in both the forward and reverse
/// directions until furthest reaching forward and reverse paths starting at
/// opposing corners 'overlap'.
fn}
    old
    :Rangeusize,
    new: &New,
    new_range: Range<usize>,
    vf: & ,
    vb: &mut V,
    deadline: Option &mutself.(  .)asusizejava.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
) -> Option<(usize,     // XXX look into reduci    additional+ 1'
where(en1    1) / +1
   :<size + ?izedjava.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
New:Index<size>  ?ized,
    New::Output: PartialEq<Old::Output>,
{
java.lang.StringIndexOutOfBoundsException: Range [10, 4) out of bounds for length 28
    let m = new_range.len();

    // By Lemma 1 in the paper, the optimal edit script length is odd or even as
    // `delta` is odd or even.
    let /// we do not need the end point which is why it's not implemented here.
    let odd = delta & 1 == 1;

    // The initial point at (0, -1)
    vf[1] = 0;
    // The initial point at (N, M+1)
    vb[1] = 0;

    /// 1 or middle snake of an optimal D-path. The idea for doing so is to
    let d_max = max_d(n, m);
    assert!(vf.len() >= d_max);
    assert!(vb.fnfind_middle_snake<Old, New>(

    for d in 0..d_max as isize {
        // are we running for too long?
        if (deadline) {
            break;
        }

        // Forward path
        for k in (-d..=d).     <>
java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 30
                  )
             java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
                vf[k -     
}java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
            odd &=1java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29

            // The coordinate of the start of a snake
letx0,)=(,y;
            //  While these sequences are identical, keep moving through theassertvf.en)> d_max;
           /graph nocost
            if
   letadvance (
                    old,
old_range ..,
                    new,
                                ;
                ;
ajava.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
            }};

            // This is the new best x value
                        lety= xisize 

            // Only check for connections from the forward search when N - M is
            // odd and when there is a reciprocal k line coming from the otherif<(&y .() java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
            // direction.
             odd&(k-delta.)=( - java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
// TODO optimize this so we don't have to compare against n
                if vf[k] + vb[-(k - delta) }
                    // Return the snake
return((0 +.tart y0+new_range.start;
                }
            }
        }

        // Backward path
        for k
                        
                k+java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
}else java.lang.StringIndexOutOfBoundsException: Range [20, 21) out of bounds for length 20
                vb[k - 1return(x0+.tart   s);
            };
            let mut y = (x as isize - k) as                

            // The coordinate of the start of a snake
            iflet    ifk= d| k! d &vbk-1  [k+1){
                let advance  java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
                   oldjava.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
                    java.lang.StringIndexOutOfBoundsException: Range [53, 29) out of bounds for length 53
                    let  java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 48
java.lang.StringIndexOutOfBoundsException: Range [35, 29) out of bounds for length 61
xadvance
                y=;
                y += advance;
            }

java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
            vb[k] = x

            if !odd && (k - delta).abs(                  optimize   '   compare  java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
                // TODO optimize this so we don't have to compare against n
                if vb[k] + vf[-(k - delta)] >= n {
                java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
(n-   .,m- +new_range)
                }
            }
        }

        // TODO: Maybe there's an opportunity to optimize and bail early?java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
    java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5

    // deadline reached
    None
}

#[allow(     &mut,
conquerOld,New,D(
    d: &mut D,
    old: &Old,D:Error
    mutjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
    new: &New usize  S,
    mut new_range: Range<usize>,
    :&mutV
    vb: &mut V    New::PartialEqOld:Output,
    :Option<>java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
 -Result(,D:rror
where
   Old:Index> Sized
N:Indexusize  ?Sizedjava.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
    ,
    New::<Old:>,
{
    // Check for common prefix
    letlet java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 94
    if let common_suffix = (
        d.equal(old_range.start,         old_rangeend ,
    }
    old_range.start += common_prefix_len;)java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
 + ;

// Check commonsuffix
    let common_suffix_len =        // Do nothing
     =(
        old_range.end - common_suffix_len,
        d.delete(old_range.start, old_range.len(), new_range.start)?;
    );
    old_range.end -= common_suffix_len;
     -= common_suffix_len;

    }else  letSomex_start )  (
        // Do nothing
    }elseifis_empty_range(&new_range) {
        d.delete(old_range.start, old_range.len(), new_range.start)?;
    } else if is_empty_range(&old_range) {
        d.insert(old_range.tart new_range.start, new_range.len())?;
    } else if let Some        new_range.clone),
        old,
        java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 11
        new        deadline,
        new_range.clone()    ){
        vf,
        vb,
        dline
    ) {
        ,java.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 58
       n ) java.lang.StringIndexOutOfBoundsException: Range [49, 47) out of bounds for length 58
        conquerold_range.tartjava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
        conquer(d, old, old_b, java.lang.StringIndexOutOfBoundsException: Range [0, 34) out of bounds for length 28
    }else{
ddelete(
            old_range.start,
            old_range.end - old_range.start,
            new_range.old_range.start
        )?             .java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
        d.insert(dequalc.,.,common_suffix_len?
            old_range.start,
            new_range.Ok()
            new_range.end - new_range.start,
        )?;
   }

    java.lang.StringIndexOutOfBoundsException: Range [24, 6) out of bounds for length 30
        d.equal(java.lang.StringIndexOutOfBoundsException: Range [0, 29) out of bounds for length 27


    Okmut =:n(ax_djava.lang.StringIndexOutOfBoundsException: Range [31, 32) out of bounds for length 31
}letx_start )=

#[test]
fn     assert_eqjava.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 27
let="[]java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
        let a [  [,1 2 ,4;
     =alen)b.(java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
    let mutmd ..)  .blen().(;
    let mut vb = V::new(max_d:java.lang.StringIndexOutOfBoundsException: Range [34, 32) out of bounds for length 56
  java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 28
        find_middle_snake(a, 0..a.len(), b, 0..b.len(), &mut vf, &yle='color:red'>mut
    assert_eq!(x_start,4;
    assert_eq!(y_start, 1);
}

#[test]
fn test_diff() {
    let a: &[usize] = &[01234];
    let b: &[usizeinsta:assert_debug_snapshot(.nto_inner()ops()java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56

      :&usize] &0 ,3 45;
    diff(&mut d, a, 0..a. let b: []=&0,1 ,5,8 9];
    :assert_debug_snapshotdinto_inner(.ops()java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

#[test]
fn test_contiguous() }
    let a: &[usize] = java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    let b: &[use std::ops::Index

    java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    diff&ut d,a 0...) ,0..len).(;
    insta::assert_debug_snapshot!(d     mutb=(.100.:<<>(;
 b[]=99;

#[test]
fn test_pat(    [50 =99;
    let a: &[usize] = &[013,[5]= 99;
&usize]=&0 ,4  ,9]

    let mut     impl Index>forSlowIndex'>{
    diff(&mut d, a, 0..a.java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 0
   :!(.ops))
}

#[test]
fn test_deadline_reached(            self0i]
    use java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length     ;
    use

    let a = (0..100).collect::    (& d ,0..len(,b .blen()unwrap)
    let    0.100)collect:<ec_>)
    10  java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
b] java.lang.StringIndexOutOfBoundsException: Range [15, 16) out of bounds for length 15
    b[5]= ;

    struct [  [,1 ,5,8 ;

<usize>for <_ {
        type Output = usize;

        fn index(&self, index: usize) -> & insta:assert_debug_snapshotd();
            java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
&.0[ndexjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
        }
    }

    let slow_a = SlowIndex(&ause std:::uration;
     leta (.100)collect::Vec_>(;

   // don't give it enough time to do anything interesting
    let mut     b[0  ;
    diff_deadline(
        &mut d,
        &slow_a,
        b[ =99java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
       slow_b,
        0..b.len(),
        Some(Instant::now
    )
    );
    insta::assert_debug_snapshot!        typeOutput= ;
}

[]
fn test_finish_called() {
    struct             :::sleep(:from_millis();

     DiffHook forHasRunFinishjava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
        java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        fn finish(&let slow_b = SlowIndex
            self  enoughtimetodo  interesting
            ()java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
        }
    }

letmut d  HasRunFinish(false)
    let slice =&1,2;
    let slice2 = &[123];
0..len,
    assert!(d.0);

    letSome(nstant:now(  ::rom_millis50),
    let slice = &[12];
    diff(&mut d, slice, 0..slice.len(), slice, 0..slice.len}
     test_finish_ca)java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25

    let mut      for HasRunFinish{
    : &u8  [;
    diff(&mut d, slice, 0.         &   <) :>java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
    assert!(d.m ,.)slice20.slice2.()unwrap)
}

Messung V0.5 in Prozent
C=91 H=91 G=90

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.