2727
2828#[ derive( Debug , PartialEq , Eq , Copy , Clone ) ]
2929pub enum LevEditType {
30- Keep ,
3130 Replace ,
3231 Insert ,
3332 Delete ,
@@ -77,19 +76,10 @@ where T: PartialEq {
7776 cache_matrix[ current + 1 + p] = x;
7877 }
7978 }
80- editops_from_cost_matrix (
81- first_string,
82- second_string,
83- matrix_columns,
84- matrix_rows,
85- prefix_len,
86- cache_matrix,
87- )
79+ editops_from_cost_matrix :: < T > ( matrix_columns, matrix_rows, prefix_len, cache_matrix)
8880}
8981
9082fn editops_from_cost_matrix < T > (
91- string1 : & [ T ] ,
92- string2 : & [ T ] ,
9383 len1 : usize ,
9484 len2 : usize ,
9585 prefix_len : usize ,
@@ -98,77 +88,57 @@ fn editops_from_cost_matrix<T>(
9888where
9989 T : PartialEq ,
10090{
91+ let mut ops = Vec :: with_capacity ( cache_matrix[ len1 * len2 - 1 ] ) ;
10192 let mut dir = 0 ;
102-
103- let mut ops: Vec < LevEditOp > = vec ! [ ] ;
104- ops. reserve ( cache_matrix[ len1 * len2 - 1 ] ) ;
105-
10693 let mut i = len1 - 1 ;
10794 let mut j = len2 - 1 ;
10895 let mut p = len1 * len2 - 1 ;
10996
110- // let string1_chars: Vec<char> = string1.chars().collect();
111- // let string2_chars: Vec<char> = string2.chars().collect();
112-
11397 //TODO this is still pretty ugly
11498 while i > 0 || j > 0 {
11599 let current_value = cache_matrix[ p] ;
116100
117- let op_type;
118-
119- if dir == -1 && j > 0 && current_value == cache_matrix[ p - 1 ] + 1 {
120- op_type = LevEditType :: Insert ;
121- } else if dir == 1 && i > 0 && current_value == cache_matrix[ p - len2] + 1 {
122- op_type = LevEditType :: Delete ;
123- } else if i > 0
124- && j > 0
125- && current_value == cache_matrix[ p - len2 - 1 ]
126- && string1[ i - 1 ] == string2[ j - 1 ]
127- {
128- op_type = LevEditType :: Keep ;
129- } else if i > 0 && j > 0 && current_value == cache_matrix[ p - len2 - 1 ] + 1 {
130- op_type = LevEditType :: Replace ;
131- }
132- /* we can't turn directly from -1 to 1, in this case it would be better
133- * to go diagonally, but check it (dir == 0) */
134- else if dir == 0 && j > 0 && current_value == cache_matrix[ p - 1 ] + 1 {
135- op_type = LevEditType :: Insert ;
136- } else if dir == 0 && i > 0 && current_value == cache_matrix[ p - len2] + 1 {
137- op_type = LevEditType :: Delete ;
138- } else {
139- panic ! ( "something went terribly wrong" ) ;
140- }
101+ // More than one operation can be possible at a time. We use `dir` to
102+ // decide when ambiguous.
103+ let is_insert = j > 0 && current_value == cache_matrix[ p - 1 ] + 1 ;
104+ let is_delete = i > 0 && current_value == cache_matrix[ p - len2] + 1 ;
105+ let is_replace = i > 0 && j > 0 && current_value == cache_matrix[ p - len2 - 1 ] + 1 ;
106+
107+ let ( op_type, new_dir) = match ( dir, is_insert, is_delete, is_replace) {
108+ ( _, false , false , false ) => ( None , 0 ) ,
109+ ( -1 , true , _, _) => ( Some ( LevEditType :: Insert ) , -1 ) ,
110+ ( 1 , _, true , _) => ( Some ( LevEditType :: Delete ) , 1 ) ,
111+ ( _, _, _, true ) => ( Some ( LevEditType :: Replace ) , 0 ) ,
112+ ( 0 , true , _, _) => ( Some ( LevEditType :: Insert ) , -1 ) ,
113+ ( 0 , _, true , _) => ( Some ( LevEditType :: Delete ) , 1 ) ,
114+ _ => panic ! ( "something went terribly wrong" ) ,
115+ } ;
141116
142- match op_type {
143- LevEditType :: Insert => {
117+ match new_dir {
118+ - 1 => {
144119 j -= 1 ;
145120 p -= 1 ;
146- dir = -1 ;
147121 }
148- LevEditType :: Delete => {
122+ 1 => {
149123 i -= 1 ;
150124 p -= len2;
151- dir = 1 ;
152125 }
153- LevEditType :: Replace => {
126+ 0 => {
154127 i -= 1 ;
155128 j -= 1 ;
156129 p -= len2 + 1 ;
157- dir = 0 ;
158- }
159- LevEditType :: Keep => {
160- i -= 1 ;
161- j -= 1 ;
162- p -= len2 + 1 ;
163- dir = 0 ;
164- /* LevEditKeep does not has to be stored */
165- continue ;
166130 }
131+ _ => panic ! ( "something went terribly wrong" ) ,
167132 } ;
168-
169- let edit_op =
170- LevEditOp { op_type, first_start : i + prefix_len, second_start : j + prefix_len } ;
171- ops. insert ( 0 , edit_op) ;
133+ dir = new_dir;
134+
135+ if let Some ( op_type) = op_type {
136+ ops. insert ( 0 , LevEditOp {
137+ op_type,
138+ first_start : i + prefix_len,
139+ second_start : j + prefix_len,
140+ } ) ;
141+ }
172142 }
173143
174144 ops
0 commit comments